package com.attendance.www.hr.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.attendance.www.hr.beans.ApprovalRecordBean;
import com.attendance.www.hr.beans.AttendanceBean;
import com.attendance.www.hr.beans.EmployeeSpecialBean;
import com.attendance.www.hr.beans.LactationBean;
import com.attendance.www.hr.beans.RequestApprovalBean;
import com.attendance.www.hr.beans.RequestApprovalPageBean;
import com.attendance.www.hr.beans.RequestApprovalParamBean;
import com.attendance.www.hr.beans.RequestApprovalSaveBean;
import com.attendance.www.hr.beans.RequestBean;
import com.attendance.www.hr.beans.RestVacationBean;
import com.attendance.www.hr.beans.RetroactiveApprovalBean;
import com.attendance.www.hr.beans.RetroactiveApprovalPageBean;
import com.attendance.www.hr.beans.RetroactiveApprovalParamBean;
import com.attendance.www.hr.beans.RetroactiveBean;
import com.attendance.www.hr.constant.AppConstant;
import com.attendance.www.hr.dao.mapper.ApprovalRecordExtMapper;
import com.attendance.www.hr.dao.mapper.ApprovalRecordMapper;
import com.attendance.www.hr.dao.mapper.ApprovalRuleMapper;
import com.attendance.www.hr.dao.mapper.AttendanceExtMapper;
import com.attendance.www.hr.dao.mapper.AttendanceMapper;
import com.attendance.www.hr.dao.mapper.AttendanceReportExtMapper;
import com.attendance.www.hr.dao.mapper.AttendanceReportMapper;
import com.attendance.www.hr.dao.mapper.DictionaryMapper;
import com.attendance.www.hr.dao.mapper.EmployeeExtMapper;
import com.attendance.www.hr.dao.mapper.EmployeeMapper;
import com.attendance.www.hr.dao.mapper.EmployeeRoleExtMapper;
import com.attendance.www.hr.dao.mapper.EmployeeRoleMapper;
import com.attendance.www.hr.dao.mapper.EmployeeSchedulMapper;
import com.attendance.www.hr.dao.mapper.EmployeeSpecialExtMapper;
import com.attendance.www.hr.dao.mapper.EmployeeSpecialMapper;
import com.attendance.www.hr.dao.mapper.FurloughBalanceMapper;
import com.attendance.www.hr.dao.mapper.HolidayMapper;
import com.attendance.www.hr.dao.mapper.LactationExtMapper;
import com.attendance.www.hr.dao.mapper.LactationMapper;
import com.attendance.www.hr.dao.mapper.LinkAddressMapper;
import com.attendance.www.hr.dao.mapper.PunchTimeMapper;
import com.attendance.www.hr.dao.mapper.RequestApprovalExtMapper;
import com.attendance.www.hr.dao.mapper.RequestExtMapper;
import com.attendance.www.hr.dao.mapper.RequestMapper;
import com.attendance.www.hr.dao.mapper.RequestReportMapper;
import com.attendance.www.hr.dao.mapper.RetroactiveApprovalExtMapper;
import com.attendance.www.hr.dao.mapper.RetroactiveExtMapper;
import com.attendance.www.hr.dao.mapper.RetroactiveMapper;
import com.attendance.www.hr.dao.mapper.RoleMapper;
import com.attendance.www.hr.dao.mapper.SchedulDayMapper;
import com.attendance.www.hr.dao.mapper.SpecialMapper;
import com.attendance.www.hr.dao.mapper.SystemConfigureMapper;
import com.attendance.www.hr.dao.mapper.TaskMapper;
import com.attendance.www.hr.entitys.ApprovalRecord;
import com.attendance.www.hr.entitys.ApprovalRecordExample;
import com.attendance.www.hr.entitys.ApprovalRule;
import com.attendance.www.hr.entitys.Attendance;
import com.attendance.www.hr.entitys.AttendanceExample;
import com.attendance.www.hr.entitys.Dictionary;
import com.attendance.www.hr.entitys.DictionaryExample;
import com.attendance.www.hr.entitys.Employee;
import com.attendance.www.hr.entitys.EmployeeExample;
import com.attendance.www.hr.entitys.EmployeeRole;
import com.attendance.www.hr.entitys.EmployeeRoleExample;
import com.attendance.www.hr.entitys.EmployeeSchedul;
import com.attendance.www.hr.entitys.EmployeeSchedulExample;
import com.attendance.www.hr.entitys.EmployeeSpecialExample;
import com.attendance.www.hr.entitys.EmployeeSpecialKey;
import com.attendance.www.hr.entitys.FurloughBalance;
import com.attendance.www.hr.entitys.FurloughBalanceExample;
import com.attendance.www.hr.entitys.Holiday;
import com.attendance.www.hr.entitys.HolidayExample;
import com.attendance.www.hr.entitys.Lactation;
import com.attendance.www.hr.entitys.LactationExample;
import com.attendance.www.hr.entitys.LinkAddress;
import com.attendance.www.hr.entitys.LinkAddressExample;
import com.attendance.www.hr.entitys.PunchTime;
import com.attendance.www.hr.entitys.PunchTimeExample;
import com.attendance.www.hr.entitys.Request;
import com.attendance.www.hr.entitys.RequestExample;
import com.attendance.www.hr.entitys.RequestReport;
import com.attendance.www.hr.entitys.RequestReportExample;
import com.attendance.www.hr.entitys.Retroactive;
import com.attendance.www.hr.entitys.RetroactiveExample;
import com.attendance.www.hr.entitys.Role;
import com.attendance.www.hr.entitys.RoleExample;
import com.attendance.www.hr.entitys.SchedulDayExample;
import com.attendance.www.hr.entitys.SchedulDayKey;
import com.attendance.www.hr.entitys.Special;
import com.attendance.www.hr.entitys.SpecialExample;
import com.attendance.www.hr.entitys.SystemConfigure;
import com.attendance.www.hr.entitys.SystemConfigureExample;
import com.attendance.www.hr.entitys.Task;
import com.attendance.www.hr.entitys.TaskExample;
import com.attendance.www.hr.exception.ResultFaultException;
import com.attendance.www.hr.service.IApprovalService;
import com.attendance.www.hr.service.IRestVacationService;
import com.attendance.www.hr.utils.FactorialUtils;
import com.attendance.www.hr.utils.MailUtils;
import com.attendance.www.hr.utils.TimeUtils;
import com.zhangkongli.frame.utils.MD5Util;

@Service
public class ApprovalServiceImpl implements IApprovalService {
	@Resource
	private AttendanceExtMapper attendanceExtDao;
	@Resource
	private RetroactiveApprovalExtMapper retroactiveApprovalExtDao;
	@Resource
	private ApprovalRuleMapper approvalRuleDao;
	@Resource
	private RequestMapper requestDao;
	@Resource
	private RoleMapper roleDao;
	@Resource
	private EmployeeRoleMapper employeeRoleDao;
	@Resource
	private EmployeeRoleExtMapper employeeRoleExtDao;
	@Resource
	private RetroactiveMapper retroactiveDao;
	@Resource
	private AttendanceMapper attendanceDao;
	@Resource
	private ApprovalRecordMapper approvalRecordDao;
	@Resource
	private ApprovalRecordExtMapper ApprovalRecordExtDao;
	@Resource
	private RequestApprovalExtMapper reqeustApprovalExtDao;
	@Resource
	private FurloughBalanceMapper furloughBalanceDao;
	@Resource
	private IRestVacationService restVacationService;
	@Resource
	private EmployeeMapper employeeDao;
	@Resource
	private EmployeeExtMapper employeeExtDao;
	@Resource
	private EmployeeSchedulMapper employeeSchedulDao;
	@Resource
	private PunchTimeMapper punchTimeDao;
	@Resource
	private SchedulDayMapper schedulDayDao;
	@Resource
	private SystemConfigureMapper systemConfigureDao;
	@Resource
	private RequestReportMapper requestReportDao;
	@Resource
	private HolidayMapper holidayDao;
	@Resource
	private LactationMapper lactationDao;
	@Resource
	private SpecialMapper specialDao;
	@Resource
	private EmployeeSpecialMapper employeeSpecialDao;
	@Resource 
	private RequestExtMapper requestExtDao;
	@Resource
	private EmployeeSpecialExtMapper employeeSpecialExtDao;
	@Resource
	private RetroactiveExtMapper retroactiveExtDao;
	@Resource
	private LactationExtMapper lactationExtDao;
	@Resource
	private LinkAddressMapper linkAddressDao;
	@Resource
	private DictionaryMapper dictionaryDao;
	@Resource
	private AttendanceReportExtMapper attendanceReportExtDao;
	@Resource
	private AttendanceReportMapper attendanceReportDao;
	@Resource
	private TaskMapper taskDao;
	
	/**
	 * 获取补签请求列表
	 */
	@Override
	public RetroactiveApprovalPageBean getRetroactiveApprovalList(RetroactiveApprovalParamBean paramBean,
			Integer employeeId) {
		if (employeeId != null && employeeId != 0) {
			List<Integer> employeeIdList=new ArrayList<Integer>();
			EmployeeRoleExample employeeRoleExample=new EmployeeRoleExample();
			employeeRoleExample.createCriteria().andEmployeeIdEqualTo(employeeId);
			List<EmployeeRole> employeeRoleList=employeeRoleDao.selectByExample(employeeRoleExample);
			for(int i=0;i<employeeRoleList.size();i++) {
				employeeIdList.addAll(employeeRoleExtDao.selectEmployeeRoleGetEmployeeIdByRoleId(employeeRoleList.get(i).getRoleId()));
			}
			employeeIdList=FactorialUtils.filterEmployeeId(employeeIdList);
			paramBean.setEmployeeIdList(employeeIdList);
			
			/*******原查询方式******/
			/*EmployeeRoleExample example = new EmployeeRoleExample();
			example.createCriteria().andEmployeeIdEqualTo(employeeId);
			List<EmployeeRole> employeeRoleList = employeeRoleDao.selectByExample(example);
			if(employeeRoleList==null || employeeRoleList.size()==0){
				throw new ResultFaultException("0_00019");
			}
			List<Integer> roleIds = new ArrayList<Integer>();
			for (EmployeeRole employeeRole : employeeRoleList) {
				roleIds.add(employeeRole.getRoleId());
			}
			paramBean.setRoleIdList(roleIds);*/
		}
		RetroactiveApprovalPageBean retroactiveApprovalPageBean=new RetroactiveApprovalPageBean();
		retroactiveApprovalPageBean.setRetroactiveApprovalList(retroactiveApprovalExtDao.getRetroactiveApprovalList(paramBean));
		retroactiveApprovalPageBean.setPageTotal(retroactiveApprovalExtDao.countOfRetroactiveApproval(paramBean));
		return retroactiveApprovalPageBean;
	}
	
	/**
	 * 获取补签请求列表
	 */
	@Override
	public RetroactiveApprovalPageBean getRetroactiveApprovalListByRole(RetroactiveApprovalParamBean paramBean,
			Integer employeeId) {
		RetroactiveApprovalPageBean retroactiveApprovalPageBean=new RetroactiveApprovalPageBean();
		List<Integer> employeeList = null;
		if (employeeId != null && employeeId != 0) {
			// 登陆员工ID，查询所属岗位，然后通过岗位查询-岗位下的员工ID
			AttendanceBean attendanceBean =new AttendanceBean();
			attendanceBean.setAttendanceDateStart(paramBean.getRetroactiveStratDate());
			attendanceBean.setAttendanceDateEnd(paramBean.getRetroactiveEndDate());
			List<Integer> roleIdList = attendanceExtDao.getRolrByEmployeeId(attendanceBean, employeeId);
			if (roleIdList != null) {
				employeeList = attendanceExtDao.getEmployeeIdListByRoleId(attendanceBean, employeeId,roleIdList);
				paramBean.setEmployeeIdList(employeeList);
				retroactiveApprovalPageBean.setRetroactiveApprovalList(retroactiveApprovalExtDao.getRetroactiveApprovalList(paramBean));
				retroactiveApprovalPageBean.setPageTotal(retroactiveApprovalExtDao.countOfRetroactiveApproval(paramBean));
			}
		}
		return retroactiveApprovalPageBean;
	}
	

	/**
	 * 补签审批操作
	 * 
	 * @param retroactiveApprovalBean
	 * @param employeeId 审批人ID 
	 * @return
	 */
	@Override
	public boolean saveRetroactiveApproval(RetroactiveApprovalBean retroactiveApprovalBean, Integer employeeId) {
		// 取得审批人岗位和级别
		EmployeeRoleExample example = new EmployeeRoleExample();
		example.createCriteria().andEmployeeIdEqualTo(employeeId);
		List<EmployeeRole> employeeRoleList = employeeRoleDao.selectByExample(example);
		if (employeeRoleList == null || employeeRoleList.size() == 0) {
			throw new ResultFaultException("10_00003");
		}
		// 取出页面选择的补签信息
		List<Integer> retroactiveIdList = retroactiveApprovalBean.getRetroactiveIdList();
		RetroactiveExample rExample = new RetroactiveExample();
		rExample.createCriteria().andRetroactiveIdIn(retroactiveIdList);
		List<Retroactive> retroactiveList = retroactiveDao.selectByExample(rExample);
		//判断长度不相等，表示为用户可能撤回申请
		if(retroactiveList.size()!=retroactiveIdList.size()){
			throw new ResultFaultException("10_00007");
		}

		for (Retroactive retroactive : retroactiveList) {
			// 取得审批规则
			ApprovalRule approvalRule = approvalRuleDao.selectByPrimaryKey(retroactive.getApprovalRuleId());
			
			// 取审批记录
			ApprovalRecordExample approvalExample = new ApprovalRecordExample();
			ApprovalRecordExample.Criteria criteria = approvalExample.createCriteria();
			criteria.andRetroactiveIdEqualTo(retroactive.getRetroactiveId());
			criteria.andEmployeeIdIsNull();
			List<ApprovalRecord> approvalRecordList = approvalRecordDao.selectByExample(approvalExample);
			if (approvalRecordList == null || approvalRecordList.size() == 0) {
				throw new ResultFaultException("10_00004");
			}
			
			ApprovalRecord approvalRecord = approvalRecordList.get(0);
			
			// 如果审批驳回，修改审批表和补签表状态，还有考勤表
			if (retroactiveApprovalBean.getApprovalState() == 3) {
				approvalRecord.setApprovalDate(new Date());
				approvalRecord.setEmployeeId(employeeId);
				approvalRecord.setIsApprove(3);
				approvalRecord.setApprovalDescription(retroactiveApprovalBean.getDescription());
				approvalRecord.setUpdateTime(new Date());
				approvalRecordDao.updateByPrimaryKeySelective(approvalRecord);
				
				retroactive.setApprovalState(retroactiveApprovalBean.getApprovalState());
				retroactive.setUpdateTime(new Date());
				retroactiveDao.updateByPrimaryKeySelective(retroactive);
				
				//修改考勤记录 --zx
				Attendance attendance=new Attendance();
				attendance.setAttendanceId(retroactive.getAttendanceId());
				attendance.setIsRepaired(3);//补签失败
				attendance.setIsApprovaled(3);//审批拒绝
				attendanceDao.updateByPrimaryKeySelective(attendance);
				
				//删除链接linkAddress
				LinkAddressExample laExample = new LinkAddressExample();
				laExample.createCriteria().andRetroactiveIdEqualTo(retroactive.getRetroactiveId());
				linkAddressDao.deleteByExample(laExample);
				Employee employee=employeeDao.selectByPrimaryKey(employeeId);
				//提醒申请人
                String textPart = "您的补签申请被拒绝<br>审批人："+employee.getChineseName();
				//邮件提醒
				this.sendEmailByReject(retroactive.getEmployeeId(),textPart,retroactiveApprovalBean.getDescription());
			}
			// 取得审批人的岗位信息
			Role approvalRole = roleDao.selectByPrimaryKey(approvalRecord.getRoleId());
			
			//审核通过
			if (retroactiveApprovalBean.getApprovalState() == 2) {
				// 判断是不是最终审批者
				int seq = approvalRecord.getSep();
				int nextSeq = 0;
				int nextApprovalRoleLevel = 0;
				if (seq == 1 && approvalRule.getTwoApprovalRole() != null) {
					nextSeq = 2;
					nextApprovalRoleLevel = approvalRule.getTwoApprovalRole();
				} else if (seq == 2 && approvalRule.getThreeApprovalRole() != null) {
					nextSeq = 3;
					nextApprovalRoleLevel = approvalRule.getThreeApprovalRole();
				} else if (seq == 3 && approvalRule.getFourApprovalRole() != null) {
					nextSeq = 4;
					nextApprovalRoleLevel = approvalRule.getFourApprovalRole();
				} else if (seq == 4 && approvalRule.getFiveApprovalRole() != null) {
					nextSeq = 5;
					nextApprovalRoleLevel = approvalRule.getFiveApprovalRole();
				}
				//保存审批结果
				approvalRecord.setApprovalDate(new Date());
				approvalRecord.setEmployeeId(employeeId);
				approvalRecord.setIsApprove(2);
				approvalRecord.setApprovalDescription(retroactiveApprovalBean.getDescription());
				approvalRecord.setUpdateTime(new Date());
				approvalRecordDao.updateByPrimaryKeySelective(approvalRecord);
				// 审批人是最终审批者，修改补签表状态
				if (nextSeq == 0) {
					retroactive.setApprovalState(retroactiveApprovalBean.getApprovalState());
					retroactive.setUpdateTime(new Date());
					retroactiveDao.updateByPrimaryKeySelective(retroactive);
					
					//更新考勤记录
					Attendance attendance = attendanceDao.selectByPrimaryKey(retroactive.getAttendanceId());
					
					//查看还有没有其他审批中的补签申请
					RetroactiveExample reExample = new RetroactiveExample();
					reExample.createCriteria().andAttendanceIdEqualTo(attendance.getAttendanceId()).andApprovalStateEqualTo(1);
					List<Retroactive> reList = retroactiveDao.selectByExample(reExample);
					if(reList!=null && reList.size()>0){
						attendance.setIsApprovaled(1);//审批中
						attendance.setIsRepaired(1);
					}else{
						attendance.setIsApprovaled(2);//审批通过
						attendance.setIsRepaired(2);
					}
					if(StringUtils.isEmpty(attendance.getStartTime()) && !StringUtils.isEmpty(retroactive.getStartTime())){
						attendance.setStartTime(retroactive.getStartTime());
					}
					if(!StringUtils.isEmpty(attendance.getStartTime()) && !StringUtils.isEmpty(retroactive.getStartTime())){
						if(TimeUtils.compareTime(attendance.getStartTime(),retroactive.getStartTime())>0){
							attendance.setStartTime(retroactive.getStartTime());
						}
					}
					if(StringUtils.isEmpty(attendance.getEndTime()) && !StringUtils.isEmpty(retroactive.getEndTime())){
						attendance.setEndTime(retroactive.getEndTime());
					}
					if(!StringUtils.isEmpty(attendance.getEndTime()) && !StringUtils.isEmpty(retroactive.getEndTime())){
						if(TimeUtils.compareTime(attendance.getEndTime(),retroactive.getEndTime())<0){
							attendance.setEndTime(retroactive.getEndTime());
						}
					}
					attendanceDao.updateByPrimaryKeySelective(attendance);

					List<Integer> employeeList = new ArrayList<Integer>();
					employeeList.add(retroactive.getEmployeeId());
					resetAttendance(attendance.getAttendanceDate(), attendance.getAttendanceDate(), employeeList);
					
					//删除链接linkAddress
					LinkAddressExample laExample = new LinkAddressExample();
					laExample.createCriteria().andRetroactiveIdEqualTo(retroactive.getRetroactiveId());
					linkAddressDao.deleteByExample(laExample);
					
					//插入任务表数据
//					this.insertTaskByParam(attendance.getAttendanceDate(), attendance.getEmployeeId());
					
				}else{
					// 审批人不是最终审批者，新建下一个审批岗位数据
					// 如果空岗位的情况，继续找下一级审批岗位
					Role resultRole = null;
					if (nextSeq == 2) {
						nextApprovalRoleLevel = approvalRule.getTwoApprovalRole();
						resultRole = getNextApprovalRoleId(approvalRole,nextApprovalRoleLevel,approvalRule.getLowestApprovalRole());
						if(resultRole==null){
							nextSeq =3;
						}
					} 
					if (nextSeq == 3) {
						nextApprovalRoleLevel = approvalRule.getThreeApprovalRole();
						resultRole = getNextApprovalRoleId(approvalRole,nextApprovalRoleLevel,approvalRule.getLowestApprovalRole());
						if(resultRole==null){
							nextSeq =4;
						}
					}
					if (nextSeq == 4) {
						nextApprovalRoleLevel = approvalRule.getFourApprovalRole();
						resultRole = getNextApprovalRoleId(approvalRole,nextApprovalRoleLevel,approvalRule.getLowestApprovalRole());
						if(resultRole==null){
							nextSeq =5;
						}
					} 
					if (nextSeq == 5) {
						nextApprovalRoleLevel = approvalRule.getFourApprovalRole();
						resultRole = getNextApprovalRoleId(approvalRole,nextApprovalRoleLevel,approvalRule.getLowestApprovalRole());
					}
					if(resultRole==null){
						throw new ResultFaultException("10_00005");
					}
					ApprovalRecord newRecord = new ApprovalRecord();
					newRecord.setRetroactiveId(retroactive.getRetroactiveId());
					newRecord.setRoleId(resultRole.getRoleId());
					newRecord.setCreateTime(new Date());
					newRecord.setSep(nextSeq);
					newRecord.setApprovalDescription(retroactiveApprovalBean.getDescription());
					newRecord.setUpdateTime(new Date());
					approvalRecordDao.insertSelective(newRecord);
				}
			}
		}
		return true;
	}

	/**
	 * 取得申请列表
	 */
	@Override
	public RequestApprovalPageBean getRequestList(RequestApprovalParamBean paramBean, Integer employeeId) {
		RequestApprovalPageBean requestApprovalPageBean=new RequestApprovalPageBean();
		if (employeeId != null && employeeId != 0) {
			List<Integer> employeeIdList=new ArrayList<Integer>();
			EmployeeRoleExample employeeRoleExample=new EmployeeRoleExample();
			employeeRoleExample.createCriteria().andEmployeeIdEqualTo(employeeId);
			List<EmployeeRole> employeeRoleList=employeeRoleDao.selectByExample(employeeRoleExample);
			for(int i=0;i<employeeRoleList.size();i++) {
				employeeIdList.addAll(employeeRoleExtDao.selectEmployeeRoleGetEmployeeIdByRoleId(employeeRoleList.get(i).getRoleId()));
			}
			employeeIdList=FactorialUtils.filterEmployeeId(employeeIdList);
			if(employeeIdList.size()<=0) {
				employeeIdList.add(-1);
			}
			paramBean.setEmployeeIdList(employeeIdList);

			/************原有查询方式*************/
			/*EmployeeRoleExample erExample = new EmployeeRoleExample();
			erExample.or().andEmployeeIdEqualTo(employeeId).andThruDateIsNull();
			erExample.or().andEmployeeIdEqualTo(employeeId).andThruDateGreaterThanOrEqualTo(new Date());
			List<EmployeeRole> employeeRoleList = employeeRoleDao.selectByExample(erExample);
			
			if(employeeRoleList ==null || employeeRoleList.size()==0){
				throw new ResultFaultException("0_00019"); 
			}
			List<Integer> roleIdList = new ArrayList<Integer>();
			for (EmployeeRole employeeRole : employeeRoleList) {
				roleIdList.add(employeeRole.getRoleId());
			}
			paramBean.setRoleIdList(roleIdList);*/
			/************************************/
		}
		requestApprovalPageBean.setRequestApprovalList(reqeustApprovalExtDao.getRequestApprovalList(paramBean));
		requestApprovalPageBean.setPageTotal(reqeustApprovalExtDao.countRequestApprovalList(paramBean));
		return requestApprovalPageBean;
	}

	@Override
	public RequestApprovalBean getRequestApprovalById(Integer requestId) {
		return reqeustApprovalExtDao.getRequestApprovalById(requestId);
	}
	
	@Override
	public RequestApprovalPageBean getRequestListByRoleId(RequestApprovalParamBean paramBean, Integer employeeId) {
		RequestApprovalPageBean requestApprovalPageBean = new RequestApprovalPageBean();
		List<Integer> employeeIdList = new ArrayList<Integer>();
		if (employeeId != null && employeeId != 0) {
			EmployeeRoleExample employeeRoleExample=new EmployeeRoleExample();
			employeeRoleExample.createCriteria().andEmployeeIdEqualTo(employeeId);
			List<EmployeeRole> employeeRoleList=employeeRoleDao.selectByExample(employeeRoleExample);
			for(int i=0;i<employeeRoleList.size();i++) {
				employeeIdList.addAll(employeeRoleExtDao.selectEmployeeRoleGetEmployeeIdByRoleId(employeeRoleList.get(i).getRoleId()));
			}
			employeeIdList=FactorialUtils.filterEmployeeId(employeeIdList);
			if(employeeIdList.size()==0){
				requestApprovalPageBean.setRequestApprovalList(new ArrayList<RequestApprovalBean>());
				requestApprovalPageBean.setPageTotal(0);
				return requestApprovalPageBean;
			}
			paramBean.setEmployeeIdList(employeeIdList);
			// 登陆员工ID，查询所属岗位，然后通过岗位查询-岗位下的员工ID
			/*AttendanceBean attendanceBean = new AttendanceBean();
			attendanceBean.setAttendanceDateStart(paramBean.getStartDate());
			attendanceBean.setAttendanceDateEnd(paramBean.getEndDate());
			List<Integer> roleIdList = attendanceExtDao.getRolrByEmployeeId(attendanceBean, employeeId);
			if (roleIdList.size()>0) {
				employeeIdList = attendanceExtDao.getEmployeeIdListByRoleId(attendanceBean, employeeId,roleIdList);
				if(employeeIdList.size()==0){
					requestApprovalPageBean.setRequestApprovalList(new ArrayList<RequestApprovalBean>());
					requestApprovalPageBean.setPageTotal(0);
					return requestApprovalPageBean;
				}
				paramBean.setEmployeeIdList(employeeIdList);
			}else{
				requestApprovalPageBean.setRequestApprovalList(new ArrayList<RequestApprovalBean>());
				requestApprovalPageBean.setPageTotal(0);
				return requestApprovalPageBean;
			}*/
		}
		requestApprovalPageBean.setRequestApprovalList(reqeustApprovalExtDao.getRequestApprovalListByRoldId(paramBean));
		requestApprovalPageBean.setPageTotal(reqeustApprovalExtDao.countRequestApprovalListByRoldId(paramBean));
		return requestApprovalPageBean;
	}
	
	/***********************************原审批，未连接BPM系统时，审批代码***********************************/
	/**
	 * 批量审批
	 * @param requestApprovalSaveBean
	 * @param employeeId 审批人ID
	 */
	/*@Override
	public void saveApprovalRequestList(RequestApprovalSaveBean requestApprovalSaveBean, Integer employeeId,boolean isHr) {
		//取得审批人岗位和级别
		EmployeeRoleExample example = new EmployeeRoleExample();
		example.createCriteria().andEmployeeIdEqualTo(employeeId);
		List<EmployeeRole> employeeRoleList = employeeRoleDao.selectByExample(example);
		if(employeeRoleList==null || employeeRoleList.size()==0){
			throw new ResultFaultException("10_00003");
		}
		
		//取出页面选择的申请信息
		List<Integer> ids = requestApprovalSaveBean.getRequestIdList();
		RequestExample requestExample = new RequestExample();
		requestExample.createCriteria().andRequestIdIn(ids)
		.andApprovalStateNotEqualTo(0);
		List<Request> requestList = requestDao.selectByExample(requestExample);
		
		//是否有撤回验证
		if (ids.size()>requestList.size()) {
			throw new ResultFaultException("10_00007");
		}
		
		for (Request request : requestList) {
			if(request.getApprovalRuleId() == null){
				throw new ResultFaultException("10_00001");
			}
			// 取得审批规则
			ApprovalRule approvalRule = approvalRuleDao.selectByPrimaryKey(request.getApprovalRuleId());
			
			//HR驳回审批的情况 
			if(isHr && requestApprovalSaveBean.getApprovalState()==3){
				Integer requestType=request.getRequestType();
				// 如果已经审批通过了，修改假期余额表
				if (request.getApprovalState() == 2) {
					if (requestType==0||requestType==1||requestType==7) {
						//取得年份
						Calendar calendar = Calendar.getInstance();
						calendar.setTime(request.getStartDate());
						Integer thisYear = calendar.get(Calendar.YEAR);
						
						FurloughBalance furloughBalance = new FurloughBalance();
						RestVacationBean restVacationBean = new RestVacationBean();
						restVacationBean.setStartDate(request.getStartDate());
						if (request.getRequestType() == 7) {
							restVacationBean.setFurloughType(0);
							restVacationBean = restVacationService.getRestVacationByType(restVacationBean, request.getEmployeeId());
						}else if(request.getRequestType()==0){
							restVacationBean.setFurloughType(request.getRequestType());
							restVacationBean = restVacationService.getRestVacationByType(restVacationBean,request.getEmployeeId());
						}else if(request.getRequestType()==1){
							restVacationBean.setFurloughType(request.getRequestType());
							restVacationBean = restVacationService.getLastYearYearFurlough(restVacationBean, request.getEmployeeId());
						}
						
						
						if (request.getHours() == null) {

						} else {//只会有hours，按天的不操作余额表
							if (request.getRequestType() != 7) {
								if(request.getRequestType()==0){
									furloughBalance.setBalanceHoursDay(restVacationBean.getRealRestVacation().add(request.getHours()));
								}else if(request.getRequestType()==1){
									Integer reportYear=request.getReportYear();
									if (reportYear.equals(thisYear)) {//同一年
										furloughBalance.setBalanceHoursDay(restVacationBean.getRealRestVacation().add(request.getHours()));
									} else {//去年
										furloughBalance.setBalanceHoursDay(restVacationBean.getRealLastYearRestVacation().add(request.getHours()));
									}
								}
							} else {
								furloughBalance.setBalanceHoursDay(restVacationBean.getRealRestVacation().subtract(request.getHours()));
							}
						}
						FurloughBalanceExample furloughBalanceExample = new FurloughBalanceExample();
						FurloughBalanceExample.Criteria furloughBalanceCriteria = furloughBalanceExample.createCriteria();
						furloughBalanceCriteria.andEmployeeIdEqualTo(request.getEmployeeId());
						if(request.getRequestType()==7){
							furloughBalanceCriteria.andFurloughBalanceTypeEqualTo(0);
						}else{
							furloughBalanceCriteria.andFurloughBalanceTypeEqualTo(request.getRequestType());
						}
						if(request.getRequestType()==1&&request.getStartDate()!=null) {
							int year = request.getReportYear();
							furloughBalance.setYear(year+"");
							furloughBalanceCriteria.andYearEqualTo(year+"");
						}
						furloughBalance.setUpdateTime(new Date());
						furloughBalanceDao.updateByExampleSelective(furloughBalance, furloughBalanceExample);
					}
				}
				//取N+1,N+2邮箱地址
				List<ApprovalRecordBean> apList = this.getApprovalRecordInfoById(Integer.toString(request.getRequestId()));
				
				//操作报表计算用的“小表”，删除其数据
				RequestReportExample requestReportExample = new RequestReportExample();
				requestReportExample.createCriteria().andRequestIdEqualTo(request.getRequestId());
				
				//查询天
//				List<RequestReport> rrList = requestReportDao.selectByExample(requestReportExample);
				//先删除数据
				requestReportDao.deleteByExample(requestReportExample);
				//查询任务表是否已有数据
				TaskExample taskExample = new TaskExample();
				taskExample.createCriteria().andEmployeeIdEqualTo(request.getEmployeeId())
				.andStateEqualTo(0);
				List<Task> taskList = taskDao.selectByExample(taskExample);//查询是否已有数据
				Map<Date, Integer> taskDateMap = new HashMap<>();
				for (Task task : taskList) {
					taskDateMap.put(task.getTaskDate(), 1);
				}
				//再循环日期，重新生成
				for (RequestReport requestReport : rrList) {
					//插入任务表数据
					if (!taskDateMap.containsKey(requestReport.getRequestReportDate())) {//不包含
						this.insertTask(requestReport.getRequestReportDate(), requestReport.getEmployeeId());
					}
				}
				
				ApprovalRecord approvalRecord = new ApprovalRecord();
				approvalRecord.setApprovalDate(new Date());
				approvalRecord.setApprovalDescription(requestApprovalSaveBean.getDescription());
				approvalRecord.setCreateTime(new Date());
				approvalRecord.setEmployeeId(employeeId);
				approvalRecord.setIsApprove(3);
				approvalRecord.setRequestId(request.getRequestId());
				approvalRecord.setUpdateTime(new Date());
				approvalRecordDao.insert(approvalRecord);
				request.setRequestId(request.getRequestId());
				request.setApprovalState(3);
				request.setUpdateTime(null);//设置更新时间
				requestDao.updateByPrimaryKeySelective(request);
				List<Integer> employeeIdList = new ArrayList<Integer>();
				employeeIdList.add(request.getEmployeeId());
				
				// 更新考勤状态
				List<Integer> updateEmployeeIdList=new ArrayList<>();
				updateEmployeeIdList.add(request.getEmployeeId());
				resetAttendance(request.getStartDate(),request.getEndDate(), updateEmployeeIdList);
				
				//查询HRBP的姓名
				Employee empHRBP = employeeDao.selectByPrimaryKey(employeeId);
				
				// 删除链接linkAddress
				//this.deleteLinkAdd(request.getRequestId());
				//邮件提醒
				//查询初始化表
//				SystemConfigure systemConfigure=systemConfigureDao.selectByPrimaryKey(1);
				//接收者邮箱（申请人）
				Employee employee = employeeDao.selectByPrimaryKey(request.getEmployeeId());
				//邮件内容
//				SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
				String textPart = null;
				
				//给N+1,N+2邮箱发邮件
				//计数器
				int count = 0;
				for (int i = 0; i < apList.size(); i++) {
//					String emails = apList.get(apList.size()-1-i).getEmail();
					String approvalIds = apList.get(apList.size()-1-i).getApproverIds();
					String requestName = apList.get(apList.size()-1-i).getRequestName();
					textPart = sdf.format(new Date()) +"，" + employee.getChineseName() + "的"+ requestName 
							+"申请被HRBP："+empHRBP.getChineseName()+"驳回，驳回原因："+requestApprovalSaveBean.getDescription()
							+"，请登陆HR考勤管理系统查看。";
//					String[] strs=emails.split(",");
					String[] strs=approvalIds.split(",");
					for(int j=0; j<strs.length; j++){
//						String email = strs[j];
						String approvalId = strs[j];
						textPart ="员工：" + employee.getChineseName()+"<br>" + 
								requestName+"申请被HRBP："+empHRBP.getChineseName()+"驳回";
						this.sendEmailByReject(Integer.parseInt(approvalId), textPart,requestApprovalSaveBean.getDescription());
						//MailUtils.send(systemConfigure, email, AppConstant.MAIL_TITLE, textPart, AppConstant.MAIL_ENDING);
					}
					count++;
					if (count==2) {
						break;
					}
				}
				//给申请人邮箱发邮件
				String requestName2 = null;
				if (apList.size()>0) {
					requestName2 = apList.get(0).getRequestName();
				}
				
				//提醒申请人
				textPart = "您的"+requestName2+"申请被HRBP："+empHRBP.getChineseName()+"驳回";
				this.sendEmailByReject(employee.getEmployeeId(), textPart,requestApprovalSaveBean.getDescription());
				//MailUtils.send(systemConfigure, employee.getEmail(), AppConstant.MAIL_TITLE, textPart, AppConstant.MAIL_ENDING);
				continue;
			}
			
			//取审批记录
			ApprovalRecordExample approvalExample = new ApprovalRecordExample();
			ApprovalRecordExample.Criteria criteria = approvalExample.createCriteria();
			criteria.andRequestIdEqualTo(request.getRequestId());
			criteria.andEmployeeIdIsNull();
			List<Integer> roleInList = new ArrayList<Integer>();
			for(EmployeeRole eRole:employeeRoleList) {
				roleInList.add(eRole.getRoleId());
			}
			criteria.andRoleIdIn(roleInList);
			List<ApprovalRecord> approvalRecordList = approvalRecordDao.selectByExample(approvalExample);
			if(approvalRecordList==null || approvalRecordList.size()==0){
				throw new ResultFaultException("10_00004");
			}
			ApprovalRecord approvalRecord = approvalRecordList.get(0);
			
			//如果审批驳回，修改审批记录和申请表状态
			if(requestApprovalSaveBean.getApprovalState()==3){
				approvalRecord.setApprovalDate(new Date());
				approvalRecord.setEmployeeId(employeeId);
				approvalRecord.setIsApprove(3);
				approvalRecord.setApprovalDescription(requestApprovalSaveBean.getDescription());
				approvalRecord.setUpdateTime(new Date());
				approvalRecordDao.updateByPrimaryKeySelective(approvalRecord);
				request.setRequestId(request.getRequestId());
				request.setApprovalState(3);
				request.setUpdateTime(null);//设置更新时间
				requestDao.updateByPrimaryKeySelective(request);
				
				// 删除链接linkAddress
				this.deleteLinkAdd(request.getRequestId());
				
				Employee employee=employeeDao.selectByPrimaryKey(employeeId);
				
				DictionaryExample dicExample = new DictionaryExample();
				dicExample.createCriteria().andDicClsEqualTo("4")
				.andDicCdEqualTo(request.getRequestType().toString());
				List<Dictionary> dicList = dictionaryDao.selectByExample(dicExample);
				//提醒申请人
				String textPart = "您的"+ dicList.get(0).getDicName()+"申请被审批人："+employee.getChineseName()+"拒绝";
				this.sendEmailByReject(request.getEmployeeId(), textPart,requestApprovalSaveBean.getDescription());
			}
			//审批通过
			else if(requestApprovalSaveBean.getApprovalState()==2){
				//取得审批人的岗位信息
				Role approvalRole = roleDao.selectByPrimaryKey(approvalRecord.getRoleId());
				//判断是不是最终审批者
				int seq = approvalRecord.getSep();
				int nextSeq = 0;
				int nextApprovalRoleLevel = 0;
				if (approvalRule.getTwoApprovalRole() != null) {
					nextSeq = 2;
					nextApprovalRoleLevel = approvalRule.getTwoApprovalRole();
					if(approvalRole.getRoleLevel()>=nextApprovalRoleLevel){
						if(approvalRule.getThreeApprovalRole() == null){
							nextSeq = 0;
						}
					}
				}
				if (approvalRule.getThreeApprovalRole() != null) {
					nextSeq = 3;
					nextApprovalRoleLevel = approvalRule.getThreeApprovalRole();
					if(approvalRole.getRoleLevel()>=nextApprovalRoleLevel){
						if(approvalRule.getFourApprovalRole() == null){
							nextSeq = 0;
						}
					}
				}
				if (approvalRule.getFourApprovalRole() != null) {
					nextSeq = 4;
					nextApprovalRoleLevel = approvalRule.getFourApprovalRole();
					if(approvalRole.getRoleLevel()>=nextApprovalRoleLevel){
						if(approvalRule.getFiveApprovalRole() == null){
							nextSeq = 0;
						}
					}
				}
				if (approvalRule.getFiveApprovalRole() != null) {
					nextSeq = 5;
					nextApprovalRoleLevel = approvalRule.getFiveApprovalRole();
					if(approvalRole.getRoleLevel()>=nextApprovalRoleLevel){
						nextSeq = 0;
					}
				}
				
				//保存审批结果
				approvalRecord.setApprovalDate(new Date());
				approvalRecord.setEmployeeId(employeeId);
				approvalRecord.setIsApprove(2);
				approvalRecord.setApprovalDescription(requestApprovalSaveBean.getDescription());
				approvalRecord.setUpdateTime(new Date());
				approvalRecordDao.updateByPrimaryKeySelective(approvalRecord);
				
				//审批人是最终审批者，修改申请表状态
				if(nextSeq==0)
				{
					request.setApprovalState(2);
					request.setUpdateTime(new Date());
					requestDao.updateByPrimaryKeySelective(request);
					//更新余额表和考勤状态
					updateAfterApproval(request);
					
					//删除链接linkAddress
					this.deleteLinkAdd(request.getRequestId());
					
					//update，先查询天
					RequestReportExample requestReportExample = new RequestReportExample();
					requestReportExample.createCriteria().andRequestIdEqualTo(request.getRequestId());
					List<RequestReport> rrList = requestReportDao.selectByExample(requestReportExample);
					//查询任务表是否已有数据
					TaskExample taskExample = new TaskExample();
					taskExample.createCriteria().andEmployeeIdEqualTo(request.getEmployeeId())
					.andStateEqualTo(0);
					List<Task> taskList = taskDao.selectByExample(taskExample);//查询是否已有数据
					Map<Date, Integer> taskDateMap = new HashMap<>();
					for (Task task : taskList) {
						taskDateMap.put(task.getTaskDate(), 1);
					}
					//再循环日期，重新生成
					for (RequestReport requestReport : rrList) {
						//插入任务表数据
						if (!taskDateMap.containsKey(requestReport.getRequestReportDate())) {//不包含
							this.insertTask(requestReport.getRequestReportDate(), requestReport.getEmployeeId());
						}
					}
					
				}else{
					// 审批人不是最终审批者，新建下一个审批岗位数据
					// 如果空岗位的情况，继续找下一级审批岗位
					Role resultRole = null;
					if (nextSeq == 2 && approvalRule.getTwoApprovalRole()!= null) {
						nextApprovalRoleLevel = approvalRule.getTwoApprovalRole();
						resultRole = getNextApprovalRoleId(approvalRole,nextApprovalRoleLevel,approvalRule.getLowestApprovalRole());
						if(resultRole!=null && resultRole.getRoleLevel()>nextApprovalRoleLevel){
							nextSeq = 3;
						}
					} 
					if (nextSeq == 3 && approvalRule.getThreeApprovalRole()!=null) {
						nextApprovalRoleLevel = approvalRule.getThreeApprovalRole();
						if(resultRole!=null && resultRole.getRoleLevel()>nextApprovalRoleLevel){
							nextSeq = 4;
						}else{
							resultRole = getNextApprovalRoleId(approvalRole,nextApprovalRoleLevel,approvalRule.getLowestApprovalRole());
							if(resultRole!=null && resultRole.getRoleLevel()>nextApprovalRoleLevel){
								nextSeq = 4;
							}
						}
						
					}
					if (nextSeq == 4 && approvalRule.getFourApprovalRole()!=null) {
						nextApprovalRoleLevel = approvalRule.getFourApprovalRole();
						if(resultRole!=null && resultRole.getRoleLevel()>nextApprovalRoleLevel){
							nextSeq = 5;
						}else{
							resultRole = getNextApprovalRoleId(approvalRole,nextApprovalRoleLevel,approvalRule.getLowestApprovalRole());
							if(resultRole!=null && resultRole.getRoleLevel()>nextApprovalRoleLevel){
								nextSeq = 5;
							}
						}
					} 
					if (nextSeq == 5 && approvalRule.getFiveApprovalRole()!=null) {
						nextApprovalRoleLevel = approvalRule.getFiveApprovalRole();
						resultRole = getNextApprovalRoleId(approvalRole,nextApprovalRoleLevel,approvalRule.getLowestApprovalRole());
					}
					if(resultRole==null){
						throw new ResultFaultException("10_00005");
					}
					ApprovalRecord newRecord = new ApprovalRecord();
					newRecord.setRequestId(approvalRecord.getRequestId());
					newRecord.setRoleId(resultRole.getRoleId());
					newRecord.setCreateTime(new Date());
					newRecord.setIsApprove(1);
					newRecord.setSep(nextSeq);
					newRecord.setUpdateTime(new Date());
					approvalRecordDao.insertSelective(newRecord);
					
					// 删除链接linkAddress
					this.deleteLinkAdd(request.getRequestId());
					//邮件提醒 
					List<ApprovalRecordBean> apList = this.getApprovalRecordInfoById(Integer.toString(request.getRequestId()));
					for (ApprovalRecordBean approvalRecordBean : apList) {
						if (approvalRecordBean.getIsApprove()!=null && approvalRecordBean.getIsApprove()==1) {
							Employee emp = employeeDao.selectByPrimaryKey(request.getEmployeeId());
							String[] strIds=approvalRecordBean.getApproverIds().split(",");
							String textPart = "员工："+ emp.getChineseName() +"的"+approvalRecordBean.getRequestName()+"申请待审批，请及时登陆HR考勤管理系统查看";
							for(int j=0; j<strIds.length; j++){
								this.sendEmail(Integer.parseInt(strIds[j]), textPart, approvalRecordBean.getRequestId(), approvalRecordBean.getRequestType());
							}
						}
					}
				}
			}
		}
	}*/
	/****************************************************************************************************/
	
	/**
	 * 批量审批  -新版本，日期：2018-12-12，将原有审批流程等代码注销
	 * @param requestApprovalSaveBean
	 * @param employeeId 审批人ID
	 */
	@Override
	public void saveApprovalRequestList(RequestApprovalSaveBean requestApprovalSaveBean, Integer employeeId,boolean isHr) {
		//取得审批人岗位和级别
		EmployeeRoleExample example = new EmployeeRoleExample();
		example.createCriteria().andEmployeeIdEqualTo(employeeId);
		List<EmployeeRole> employeeRoleList = employeeRoleDao.selectByExample(example);
		if(employeeRoleList==null || employeeRoleList.size()==0){
			throw new ResultFaultException("10_00003");
		}
		
		//取出页面选择的申请信息
		List<Integer> ids = requestApprovalSaveBean.getRequestIdList();
		RequestExample requestExample = new RequestExample();
		requestExample.createCriteria().andRequestIdIn(ids)
		.andApprovalStateNotEqualTo(0);
		List<Request> requestList = requestDao.selectByExample(requestExample);
		
		//是否有撤回验证
		if (ids.size()>requestList.size()) {
			throw new ResultFaultException("10_00007");
		}
		
		for (Request request : requestList) {
			/*if(request.getApprovalRuleId() == null){
				throw new ResultFaultException("10_00001");
			}
			// 取得审批规则
			ApprovalRule approvalRule = approvalRuleDao.selectByPrimaryKey(request.getApprovalRuleId());*/
			
			//HR驳回审批的情况 
			if(isHr && requestApprovalSaveBean.getApprovalState()==3){
				Integer requestType=request.getRequestType();
				// 如果已经审批通过了，修改假期余额表
				if (request.getApprovalState() == 2) {
					if (requestType==0||requestType==1||requestType==7) {
						//取得年份
						Calendar calendar = Calendar.getInstance();
						calendar.setTime(request.getStartDate());
						Integer thisYear = calendar.get(Calendar.YEAR);
						
						FurloughBalance furloughBalance = new FurloughBalance();
						RestVacationBean restVacationBean = new RestVacationBean();
						restVacationBean.setStartDate(request.getStartDate());
						if (request.getRequestType() == 7) {
							restVacationBean.setFurloughType(0);
							restVacationBean = restVacationService.getRestVacationByType(restVacationBean, request.getEmployeeId());
						}else if(request.getRequestType()==0){
							restVacationBean.setFurloughType(request.getRequestType());
							restVacationBean = restVacationService.getRestVacationByType(restVacationBean,request.getEmployeeId());
						}else if(request.getRequestType()==1){
							restVacationBean.setFurloughType(request.getRequestType());
							restVacationBean = restVacationService.getLastYearYearFurlough(restVacationBean, request.getEmployeeId());
						}
						
						
						if (request.getHours() == null) {

						} else {//只会有hours，按天的不操作余额表
							if (request.getRequestType() != 7) {
								if(request.getRequestType()==0){
									furloughBalance.setBalanceHoursDay(restVacationBean.getRealRestVacation().add(request.getHours()));
								}else if(request.getRequestType()==1){
									Integer reportYear=request.getReportYear();
									if (reportYear.equals(thisYear)) {//同一年
										furloughBalance.setBalanceHoursDay(restVacationBean.getRealRestVacation().add(request.getHours()));
									} else {//去年
										furloughBalance.setBalanceHoursDay(restVacationBean.getRealLastYearRestVacation().add(request.getHours()));
									}
								}
							} else {
								furloughBalance.setBalanceHoursDay(restVacationBean.getRealRestVacation().subtract(request.getHours()));
							}
						}
						FurloughBalanceExample furloughBalanceExample = new FurloughBalanceExample();
						FurloughBalanceExample.Criteria furloughBalanceCriteria = furloughBalanceExample.createCriteria();
						furloughBalanceCriteria.andEmployeeIdEqualTo(request.getEmployeeId());
						if(request.getRequestType()==7){
							furloughBalanceCriteria.andFurloughBalanceTypeEqualTo(0);
						}else{
							furloughBalanceCriteria.andFurloughBalanceTypeEqualTo(request.getRequestType());
						}
						if(request.getRequestType()==1&&request.getStartDate()!=null) {
							int year = request.getReportYear();
							furloughBalance.setYear(year+"");
							furloughBalanceCriteria.andYearEqualTo(year+"");
						}
						furloughBalance.setUpdateTime(new Date());
						furloughBalanceDao.updateByExampleSelective(furloughBalance, furloughBalanceExample);
					}
				}
				//取N+1,N+2邮箱地址
				List<ApprovalRecordBean> apList = this.getApprovalRecordInfoById(Integer.toString(request.getRequestId()));
				
				//操作报表计算用的“小表”，删除其数据
				RequestReportExample requestReportExample = new RequestReportExample();
				requestReportExample.createCriteria().andRequestIdEqualTo(request.getRequestId());
				
				//查询天
//				List<RequestReport> rrList = requestReportDao.selectByExample(requestReportExample);
				//先删除数据
				requestReportDao.deleteByExample(requestReportExample);
				//查询任务表是否已有数据
				/*TaskExample taskExample = new TaskExample();
				taskExample.createCriteria().andEmployeeIdEqualTo(request.getEmployeeId())
				.andStateEqualTo(0);
				List<Task> taskList = taskDao.selectByExample(taskExample);//查询是否已有数据
				Map<Date, Integer> taskDateMap = new HashMap<>();
				for (Task task : taskList) {
					taskDateMap.put(task.getTaskDate(), 1);
				}
				//再循环日期，重新生成
				for (RequestReport requestReport : rrList) {
					//插入任务表数据
					if (!taskDateMap.containsKey(requestReport.getRequestReportDate())) {//不包含
						this.insertTask(requestReport.getRequestReportDate(), requestReport.getEmployeeId());
					}
				}*/
				
				ApprovalRecord approvalRecord = new ApprovalRecord();
				approvalRecord.setApprovalDate(new Date());
				approvalRecord.setApprovalDescription(requestApprovalSaveBean.getDescription());
				approvalRecord.setCreateTime(new Date());
				approvalRecord.setEmployeeId(employeeId);
				approvalRecord.setIsApprove(3);
				approvalRecord.setRequestId(request.getRequestId());
				ApprovalRecordExample approvalRecordExample=new ApprovalRecordExample();
				approvalRecordExample.createCriteria().andRequestIdEqualTo(request.getRequestId());
				List<ApprovalRecord> approvalRecordList=approvalRecordDao.selectByExample(approvalRecordExample);
				if(approvalRecordList.size()>0) {
					approvalRecord.setSep(approvalRecordList.get(approvalRecordList.size()-1).getSep()+1);
				}else {
					approvalRecord.setSep(0);
				}
				approvalRecord.setUpdateTime(new Date());
				approvalRecordDao.insert(approvalRecord);
				
				request.setRequestId(request.getRequestId());
				request.setApprovalState(3);
				request.setUpdateTime(null);//设置更新时间
				requestDao.updateByPrimaryKeySelective(request);
				List<Integer> employeeIdList = new ArrayList<Integer>();
				employeeIdList.add(request.getEmployeeId());
				
				// 更新考勤状态
				List<Integer> updateEmployeeIdList=new ArrayList<>();
				updateEmployeeIdList.add(request.getEmployeeId());
				resetAttendance(request.getStartDate(),request.getEndDate(), updateEmployeeIdList);
				
				//查询HRBP的姓名
				Employee empHRBP = employeeDao.selectByPrimaryKey(employeeId);
				
				// 删除链接linkAddress
				//this.deleteLinkAdd(request.getRequestId());
				//邮件提醒
				//查询初始化表
//				SystemConfigure systemConfigure=systemConfigureDao.selectByPrimaryKey(1);
				//接收者邮箱（申请人）
				Employee employee = employeeDao.selectByPrimaryKey(request.getEmployeeId());
				//邮件内容
//				SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
				String textPart = null;
				
				//给N+1,N+2邮箱发邮件
				/*//计数器
				int count = 0;
				for (int i = 0; i < apList.size(); i++) {
//					String emails = apList.get(apList.size()-1-i).getEmail();
					String approvalIds = apList.get(apList.size()-1-i).getApproverIds();
					String requestName = apList.get(apList.size()-1-i).getRequestName();
					textPart = sdf.format(new Date()) +"，" + employee.getChineseName() + "的"+ requestName 
							+"申请被HRBP："+empHRBP.getChineseName()+"驳回，驳回原因："+requestApprovalSaveBean.getDescription()
							+"，请登陆HR考勤管理系统查看。";
//					String[] strs=emails.split(",");
					String[] strs=approvalIds.split(",");
					for(int j=0; j<strs.length; j++){
//						String email = strs[j];
						String approvalId = strs[j];
						textPart ="员工：" + employee.getChineseName()+"<br>" + 
								requestName+"申请被HRBP："+empHRBP.getChineseName()+"驳回";
						this.sendEmailByReject(Integer.parseInt(approvalId), textPart,requestApprovalSaveBean.getDescription());
						//MailUtils.send(systemConfigure, email, AppConstant.MAIL_TITLE, textPart, AppConstant.MAIL_ENDING);
					}
					count++;
					if (count==2) {
						break;
					}
				}*/
				//给申请人邮箱发邮件
				String requestName2 = null;
				if (apList.size()>0) {
					requestName2 = apList.get(0).getRequestName();
				}
				
				//提醒申请人
				textPart = "您的"+requestName2+"申请被HRBP："+empHRBP.getChineseName()+"驳回";
				this.sendEmailByReject(employee.getEmployeeId(), textPart,requestApprovalSaveBean.getDescription());
				//MailUtils.send(systemConfigure, employee.getEmail(), AppConstant.MAIL_TITLE, textPart, AppConstant.MAIL_ENDING);
				continue;
			}
			
			//取审批记录
			/*ApprovalRecordExample approvalExample = new ApprovalRecordExample();
			ApprovalRecordExample.Criteria criteria = approvalExample.createCriteria();
			criteria.andRequestIdEqualTo(request.getRequestId());
			criteria.andEmployeeIdIsNull();
			List<Integer> roleInList = new ArrayList<Integer>();
			for(EmployeeRole eRole:employeeRoleList) {
				roleInList.add(eRole.getRoleId());
			}
			criteria.andRoleIdIn(roleInList);
			List<ApprovalRecord> approvalRecordList = approvalRecordDao.selectByExample(approvalExample);
			if(approvalRecordList==null || approvalRecordList.size()==0){
				throw new ResultFaultException("10_00004");
			}*/
			//ApprovalRecord approvalRecord = approvalRecordList.get(0);
			
			//如果审批驳回，修改审批记录和申请表状态
			if(requestApprovalSaveBean.getApprovalState()==3){
				/*approvalRecord.setApprovalDate(new Date());
				approvalRecord.setEmployeeId(employeeId);
				approvalRecord.setIsApprove(3);
				approvalRecord.setApprovalDescription(requestApprovalSaveBean.getDescription());
				approvalRecord.setUpdateTime(new Date());
				approvalRecordDao.updateByPrimaryKeySelective(approvalRecord);*/
				request.setRequestId(request.getRequestId());
				request.setApprovalState(3);
				request.setUpdateTime(null);//设置更新时间
				requestDao.updateByPrimaryKeySelective(request);
				
				// 删除链接linkAddress
				this.deleteLinkAdd(request.getRequestId());
				
				Employee employee=employeeDao.selectByPrimaryKey(employeeId);
				
				DictionaryExample dicExample = new DictionaryExample();
				dicExample.createCriteria().andDicClsEqualTo("4")
				.andDicCdEqualTo(request.getRequestType().toString());
				List<Dictionary> dicList = dictionaryDao.selectByExample(dicExample);
				//提醒申请人
				String textPart = "您的"+ dicList.get(0).getDicName()+"申请被审批人："+employee.getChineseName()+"拒绝";
				this.sendEmailByReject(request.getEmployeeId(), textPart,requestApprovalSaveBean.getDescription());
			}
			//审批通过
			else if(requestApprovalSaveBean.getApprovalState()==2){
				/*//取得审批人的岗位信息
				Role approvalRole = roleDao.selectByPrimaryKey(approvalRecord.getRoleId());
				//判断是不是最终审批者
				int seq = approvalRecord.getSep();
				int nextSeq = 0;
				int nextApprovalRoleLevel = 0;
				if (approvalRule.getTwoApprovalRole() != null) {
					nextSeq = 2;
					nextApprovalRoleLevel = approvalRule.getTwoApprovalRole();
					if(approvalRole.getRoleLevel()>=nextApprovalRoleLevel){
						if(approvalRule.getThreeApprovalRole() == null){
							nextSeq = 0;
						}
					}
				}
				if (approvalRule.getThreeApprovalRole() != null) {
					nextSeq = 3;
					nextApprovalRoleLevel = approvalRule.getThreeApprovalRole();
					if(approvalRole.getRoleLevel()>=nextApprovalRoleLevel){
						if(approvalRule.getFourApprovalRole() == null){
							nextSeq = 0;
						}
					}
				}
				if (approvalRule.getFourApprovalRole() != null) {
					nextSeq = 4;
					nextApprovalRoleLevel = approvalRule.getFourApprovalRole();
					if(approvalRole.getRoleLevel()>=nextApprovalRoleLevel){
						if(approvalRule.getFiveApprovalRole() == null){
							nextSeq = 0;
						}
					}
				}
				if (approvalRule.getFiveApprovalRole() != null) {
					nextSeq = 5;
					nextApprovalRoleLevel = approvalRule.getFiveApprovalRole();
					if(approvalRole.getRoleLevel()>=nextApprovalRoleLevel){
						nextSeq = 0;
					}
				}
				
				//保存审批结果
				approvalRecord.setApprovalDate(new Date());
				approvalRecord.setEmployeeId(employeeId);
				approvalRecord.setIsApprove(2);
				approvalRecord.setApprovalDescription(requestApprovalSaveBean.getDescription());
				approvalRecord.setUpdateTime(new Date());
				approvalRecordDao.updateByPrimaryKeySelective(approvalRecord);*/
				
				//审批人是最终审批者，修改申请表状态
				//if(nextSeq==0)
				//{
					/*request.setApprovalState(2);
					request.setUpdateTime(new Date());
					requestDao.updateByPrimaryKeySelective(request);
					//更新余额表和考勤状态
					updateAfterApproval(request);
					
					//删除链接linkAddress
					this.deleteLinkAdd(request.getRequestId());*/
					
					//update，先查询天
					/*RequestReportExample requestReportExample = new RequestReportExample();
					requestReportExample.createCriteria().andRequestIdEqualTo(request.getRequestId());
					List<RequestReport> rrList = requestReportDao.selectByExample(requestReportExample);
					//查询任务表是否已有数据
					TaskExample taskExample = new TaskExample();
					taskExample.createCriteria().andEmployeeIdEqualTo(request.getEmployeeId())
					.andStateEqualTo(0);
					List<Task> taskList = taskDao.selectByExample(taskExample);//查询是否已有数据
					Map<Date, Integer> taskDateMap = new HashMap<>();
					for (Task task : taskList) {
						taskDateMap.put(task.getTaskDate(), 1);
					}
					//再循环日期，重新生成
					for (RequestReport requestReport : rrList) {
						//插入任务表数据
						if (!taskDateMap.containsKey(requestReport.getRequestReportDate())) {//不包含
							this.insertTask(requestReport.getRequestReportDate(), requestReport.getEmployeeId());
						}
					}*/
					
				//}else{
					// 审批人不是最终审批者，新建下一个审批岗位数据
					// 如果空岗位的情况，继续找下一级审批岗位
					/*Role resultRole = null;
					if (nextSeq == 2 && approvalRule.getTwoApprovalRole()!= null) {
						nextApprovalRoleLevel = approvalRule.getTwoApprovalRole();
						resultRole = getNextApprovalRoleId(approvalRole,nextApprovalRoleLevel,approvalRule.getLowestApprovalRole());
						if(resultRole!=null && resultRole.getRoleLevel()>nextApprovalRoleLevel){
							nextSeq = 3;
						}
					} 
					if (nextSeq == 3 && approvalRule.getThreeApprovalRole()!=null) {
						nextApprovalRoleLevel = approvalRule.getThreeApprovalRole();
						if(resultRole!=null && resultRole.getRoleLevel()>nextApprovalRoleLevel){
							nextSeq = 4;
						}else{
							resultRole = getNextApprovalRoleId(approvalRole,nextApprovalRoleLevel,approvalRule.getLowestApprovalRole());
							if(resultRole!=null && resultRole.getRoleLevel()>nextApprovalRoleLevel){
								nextSeq = 4;
							}
						}
						
					}
					if (nextSeq == 4 && approvalRule.getFourApprovalRole()!=null) {
						nextApprovalRoleLevel = approvalRule.getFourApprovalRole();
						if(resultRole!=null && resultRole.getRoleLevel()>nextApprovalRoleLevel){
							nextSeq = 5;
						}else{
							resultRole = getNextApprovalRoleId(approvalRole,nextApprovalRoleLevel,approvalRule.getLowestApprovalRole());
							if(resultRole!=null && resultRole.getRoleLevel()>nextApprovalRoleLevel){
								nextSeq = 5;
							}
						}
					} 
					if (nextSeq == 5 && approvalRule.getFiveApprovalRole()!=null) {
						nextApprovalRoleLevel = approvalRule.getFiveApprovalRole();
						resultRole = getNextApprovalRoleId(approvalRole,nextApprovalRoleLevel,approvalRule.getLowestApprovalRole());
					}
					if(resultRole==null){
						throw new ResultFaultException("10_00005");
					}
					ApprovalRecord newRecord = new ApprovalRecord();
					newRecord.setRequestId(approvalRecord.getRequestId());
					newRecord.setRoleId(resultRole.getRoleId());
					newRecord.setCreateTime(new Date());
					newRecord.setIsApprove(1);
					newRecord.setSep(nextSeq);
					newRecord.setUpdateTime(new Date());
					approvalRecordDao.insertSelective(newRecord);*/
					
					// 删除链接linkAddress
					/*this.deleteLinkAdd(request.getRequestId());
					//邮件提醒 
					List<ApprovalRecordBean> apList = this.getApprovalRecordInfoById(Integer.toString(request.getRequestId()));
					for (ApprovalRecordBean approvalRecordBean : apList) {
						if (approvalRecordBean.getIsApprove()!=null && approvalRecordBean.getIsApprove()==1) {
							Employee emp = employeeDao.selectByPrimaryKey(request.getEmployeeId());
							String[] strIds=approvalRecordBean.getApproverIds().split(",");
							String textPart = "员工："+ emp.getChineseName() +"的"+approvalRecordBean.getRequestName()+"申请待审批，请及时登陆HR考勤管理系统查看";
							for(int j=0; j<strIds.length; j++){
								this.sendEmail(Integer.parseInt(strIds[j]), textPart, approvalRecordBean.getRequestId(), approvalRecordBean.getRequestType());
							}
						}
					}*/
				//}
			}
		}
	}
	
	

	/*
	 * 审批通过后，更新相关数据
	 */
	@Override
	public void updateAfterApproval(Request request){
		
		saveOrGetRequestMinutes(request, 2);
		
		//取得年份
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(request.getStartDate());
		Integer thisYear = calendar.get(Calendar.YEAR);
	
		if(request.getRequestType()==7 || request.getRequestType()==1 || request.getRequestType()==0){
			//添加剩余额度表
			FurloughBalance furloughBalance =new FurloughBalance();
			furloughBalance.setEmployeeId(request.getEmployeeId());
			furloughBalance.setFurloughBalanceType(request.getRequestType());
			if(request.getRequestType()==7){
				furloughBalance.setFurloughBalanceType(0);
			}
			RestVacationBean restVacationBean = new RestVacationBean();
			if(request.getRequestType()==7){
				restVacationBean.setFurloughType(0);
				restVacationBean = restVacationService.getRestVacationByType(restVacationBean,request.getEmployeeId());
			}else if(request.getRequestType()==0){
				restVacationBean.setFurloughType(request.getRequestType());
				restVacationBean.setStartDate(request.getStartDate());
				restVacationBean = restVacationService.getRestVacationByType(restVacationBean,request.getEmployeeId());
			}else if(request.getRequestType()==1){
				restVacationBean.setFurloughType(request.getRequestType());
				restVacationBean.setStartDate(request.getStartDate());
				restVacationBean = restVacationService.getLastYearYearFurlough(restVacationBean, request.getEmployeeId());
			}
			
			if(request.getHours()==null){//按天申请的，也不会进入判断
//				if(request.getRequestType()==7){
//					furloughBalance.setBalanceHoursDay(restVacationBean.getRealRestVacation().add(new BigDecimal(request.getDayNumber())));
//				}else{
//					furloughBalance.setBalanceHoursDay(restVacationBean.getRealRestVacation().subtract(new BigDecimal(request.getDayNumber())));
//				}
			}else{
				if(request.getRequestType()==7){
					furloughBalance.setBalanceHoursDay(restVacationBean.getRealRestVacation().add(request.getHours()));
				}else if(request.getRequestType()==0){
					furloughBalance.setBalanceHoursDay(restVacationBean.getRealRestVacation().subtract(request.getHours()));
				}else if(request.getRequestType()==1){
					Integer reportYear=request.getReportYear();
					if (reportYear.equals(thisYear)) {//同一年
						furloughBalance.setBalanceHoursDay(restVacationBean.getRealRestVacation().subtract(request.getHours()));
					} else {//去年
						furloughBalance.setBalanceHoursDay(restVacationBean.getRealLastYearRestVacation().subtract(request.getHours()));
					}
				}
			}
			FurloughBalanceExample furloughBalanceExample = new FurloughBalanceExample();
			FurloughBalanceExample.Criteria furloughBalanceCriteria = furloughBalanceExample.createCriteria();
			if(request.getRequestType()==1&&request.getStartDate()!=null) {
//				Calendar c = Calendar.getInstance();
//		        c.setTime(request.getStartDate());
//		        int year = c.get(Calendar.YEAR);
		        int year = request.getReportYear();
		        furloughBalance.setYear(year+"");
				furloughBalanceCriteria.andYearEqualTo(year+"");
			}
			furloughBalanceCriteria.andEmployeeIdEqualTo(request.getEmployeeId());
			if(request.getRequestType()==7){
				furloughBalanceCriteria.andFurloughBalanceTypeEqualTo(0);
			}else{
				furloughBalanceCriteria.andFurloughBalanceTypeEqualTo(request.getRequestType());
			}
			List<FurloughBalance> furloughBalanceList= furloughBalanceDao.selectByExample(furloughBalanceExample);
			if(furloughBalanceList.size()>0){
				furloughBalance.setFurloughBalanceId(furloughBalanceList.get(0).getFurloughBalanceId());
				furloughBalance.setUpdateTime(new Date());
				furloughBalanceDao.updateByPrimaryKeySelective(furloughBalance);
			}else{
				//
				furloughBalance.setInitHoursDay(restVacationBean.getTotalVacation());
				furloughBalanceDao.insertSelective(furloughBalance);
			}
		}

		//如果不是休假类型，跳过后续操作
		if(request.getRequestType() == 7){
			return;
		}
		
		//开始日期
		Date startDate = request.getStartDate();
		//结束日期
		Date endDate = request.getEndDate();
		
		//按分钟计算/按天计算
		boolean isMinute = true;
		if(request.getRequestType()==3 || request.getRequestType()==4 || request.getRequestType()==11 || request.getRequestType()==13){
			isMinute = false;
		}
		
		//重计算
		List<Integer> employeeIdList=new ArrayList<>();
		employeeIdList.add(request.getEmployeeId());
		this.resetAttendance(startDate, endDate, employeeIdList);
		
	}

	/*
	 * 补签审批通过后，更新相关数据
	 */
	private void updateAfterRetroactiveApproval(Retroactive retroactive){
		
		//考勤数据
		Attendance attendance = attendanceDao.selectByPrimaryKey(retroactive.getAttendanceId());
		Date retroactiveDate = attendance.getAttendanceDate();
		
		//取得人员的排班时间
		EmployeeSchedulExample employeeSchedulExample = new EmployeeSchedulExample();
		employeeSchedulExample.or().andEmployeeIdEqualTo(attendance.getEmployeeId()).andFromDateLessThanOrEqualTo(retroactiveDate).andThruDateGreaterThanOrEqualTo(retroactiveDate);
		employeeSchedulExample.or().andEmployeeIdEqualTo(attendance.getEmployeeId()).andFromDateLessThanOrEqualTo(retroactiveDate).andThruDateIsNull();
		employeeSchedulExample.setOrderByClause("from_date desc");
		List<EmployeeSchedul> employeeSchedulList = employeeSchedulDao.selectByExample(employeeSchedulExample);
		if(employeeSchedulList==null || employeeSchedulList.size()==0){
			//未找到排班信息
			throw new ResultFaultException("5_00006"); 
		}
		//取得打卡时间配置记录
		PunchTime punchTime = punchTimeDao.selectByPrimaryKey(employeeSchedulList.get(0).getPunchTimeId());
		//取得应出勤时长
		Integer punchMinutes = TimeUtils.differMinutes(punchTime.getStartFromTime(), punchTime.getEndFromTime());
		
		Integer startStatus = 1;
		Integer endStatus = 1;
		String attendanceStime = attendance.getStartTime();
		String attendanceEtime = attendance.getEndTime();
		String stime = "";
		String etime = "";
		if(StringUtils.isEmpty(attendanceStime)){
			attendanceStime = attendance.getOriginalStartTime();
		}
		if(StringUtils.isEmpty(attendanceEtime)){
			attendanceEtime = attendance.getOriginalEndTime();
		}		
		
		if(!StringUtils.isEmpty(retroactive.getStartTime())){
			//早上签到补签
			if(StringUtils.isEmpty(attendanceStime)){
				attendanceStime = retroactive.getStartTime();;
			}else{
				if(TimeUtils.compareTime(retroactive.getStartTime(), attendanceStime)<0){
					attendanceStime = retroactive.getStartTime();
				}
			}
		}else{
			//晚上签退补签
			if(StringUtils.isEmpty(attendanceEtime)){
				attendanceEtime = retroactive.getEndTime();
			}else{
				if(TimeUtils.compareTime(attendanceEtime, retroactive.getEndTime())<0){
					attendanceEtime = retroactive.getEndTime();
				}
			}
		}
		
		if(StringUtils.isEmpty(attendanceStime)){
			stime = punchTime.getStartFromTime();
		}else{
			if(TimeUtils.compareTime(attendanceStime, punchTime.getStartFromTime())<0){
				stime = punchTime.getStartFromTime();
			}else{
				stime = attendanceStime;
			}
		}
		
		if(StringUtils.isEmpty(attendanceEtime)){
			etime = punchTime.getEndToTime();
		}else{
			if(TimeUtils.compareTime(attendanceEtime, punchTime.getEndToTime())>0){
				etime = punchTime.getEndToTime();
			}else{
				etime = attendanceEtime;
			}
		}
		
		//取得出勤时长
		Integer tempMinutes = TimeUtils.differMinutes(stime,etime);
		//出勤时间不够
		if(tempMinutes<punchMinutes){
			if(TimeUtils.compareTime(punchTime.getStartToTime(), stime)<0){
				if(TimeUtils.differMinutes(punchTime.getStartToTime(), stime) > punchTime.getStartInterval()){
					// 早旷工
					startStatus = 5;
				}else{
					// 早迟到
					startStatus = 2;
				}
			}
			if(TimeUtils.compareTime(punchTime.getEndFromTime(), etime)>0){
				if(TimeUtils.differMinutes(etime,punchTime.getEndFromTime()) > punchTime.getEndInterval()){
					// 晚 旷工
					endStatus = 5;
				}else{
					// 晚 早退
					endStatus = 3;
				}
			}
			if(punchMinutes - tempMinutes > punchTime.getEndInterval()){
				// 晚 旷工
				endStatus = 5;
			}
		}else{
			//正常
		}
		
		if(startStatus == 5 || endStatus == 5){
			//旷工
			attendance.setAttendanceState(5);
		}else if (startStatus == 2 && endStatus == 1){
			//迟到
			attendance.setAttendanceState(2);
		}else if (startStatus == 1 && endStatus == 3){
			//早退
			attendance.setAttendanceState(3);
		}else if (startStatus == 2 && endStatus == 3){
			//迟到并早退
			attendance.setAttendanceState(5);
		}else{
			//正常
			attendance.setAttendanceState(1);
		}
		if(!StringUtils.isEmpty(attendanceStime)){
			attendance.setStartTime(attendanceStime);
		}
		if(!StringUtils.isEmpty(attendanceEtime)){
			attendance.setEndTime(attendanceEtime);
		}
		attendance.setUpdateTime(new Date());
		attendance.setIsApprovaled(2);
		attendance.setIsRepaired(2);
		attendanceDao.updateByPrimaryKeySelective(attendance);
	}
	
	/*
	 * 通过审批人的岗位，取下一级别审批人的岗位
	 * 找不到合适的岗位时，返回null
	 */
	@Override
	public Role getNextApprovalRoleId(Role approvalRole, Integer nextApprovalRoleLevel,Integer lowestApprovalRoleLevel) {
		
		// 取所有父级岗位Id
		String rolePath = approvalRole.getRolePath();
		String[] roleIds = reverseArray(rolePath.split("-"));
		List<Integer> roleIdList = new ArrayList<Integer>();
		for (String roleid : roleIds) {
			if(StringUtils.isEmpty(roleid)){
				continue;
			}
			int intRoleId = Integer.parseInt(roleid);
			//跳过本人
			if(intRoleId == approvalRole.getRoleId()){
				continue;
			}
			// 取N+1岗位id
			if (nextApprovalRoleLevel == 99) {
				if(haveEmployeeInRole(intRoleId)){
					Role nextRole = roleDao.selectByPrimaryKey(intRoleId);
					//判断最低审批级别
					if(lowestApprovalRoleLevel == null || lowestApprovalRoleLevel<= nextRole.getRoleLevel()){
						return nextRole;
					}else{
						continue;
					}
				}else{
					//空岗位跳过
					continue;
				}
			}else{
				roleIdList.add(intRoleId);	
			}
		}
		if (roleIdList.size()==0) {
			throw new ResultFaultException("10_00005");
		}
		
		// 取指定级别的审批人岗位
		RoleExample roleExample = new RoleExample();
		roleExample.createCriteria().andRoleIdIn(roleIdList);
		roleExample.setOrderByClause("role_level");
		List<Role> roleList = roleDao.selectByExample(roleExample);
		if(roleList==null || roleList.size()==0){
			//没有当前级别的岗位
			return null;
		}
		for (Role role : roleList) {
			//空岗位
			if(haveEmployeeInRole(role.getRoleId())){
				return role;
			}
		}
		return null;
	}
	
	/*
	 * 判断当前岗位是不是空岗位 
	 */
	private boolean haveEmployeeInRole(Integer roleId){
		EmployeeRoleExample example = new EmployeeRoleExample();
		example.or().andRoleIdEqualTo(roleId).andFromDateLessThanOrEqualTo(new Date()).andThruDateIsNull();
		example.or().andRoleIdEqualTo(roleId).andFromDateLessThanOrEqualTo(new Date()).andThruDateGreaterThanOrEqualTo(new Date());

		List<EmployeeRole> employeeRoleList = employeeRoleDao.selectByExample(example);
		if(employeeRoleList==null || employeeRoleList.size()==0){
			return false;
		}
		List<Integer> employeeIds = new ArrayList<Integer>();
		for (EmployeeRole employeeRole : employeeRoleList) {
			employeeIds.add(employeeRole.getEmployeeId());
		}
		EmployeeExample employeeExample = new EmployeeExample();
		employeeExample.createCriteria().andEmployeeIdIn(employeeIds)
		.andEmployeeIsSeparatedEqualTo(0);
		
		List<Employee> employeeList = employeeDao.selectByExample(employeeExample);
		if(employeeList==null || employeeList.size()==0){
			return false;
		}
		return true;
	}

	/*
	 * 函数：reverseArray 功能：实现 数组翻转 例如：{'a','b','c','d'}变成{'d','c','b','a'}
	 */
	private String[] reverseArray(String[] Array) {
		String[] new_array = new String[Array.length];
		for (int i = 0; i < Array.length; i++) {
			// 反转后数组的第一个元素等于源数组的最后一个元素：
			new_array[i] = Array[Array.length - i - 1];
		}
		return new_array;
	}

	/**
	 * 查询某人申请的审批信息--张鑫
	 */
	@Override
	public List<ApprovalRecordBean> getApprovalRecordInfoById(String requestId) {
		List<ApprovalRecordBean> approvalRecordBeanList = ApprovalRecordExtDao.getApprovalRecordInfoByHR(Integer.parseInt(requestId));
		return approvalRecordBeanList;

		//查询审批节点人员2018-10-12
		//ApprovalRecordExample approvalRecordExample=new ApprovalRecordExample();
		//approvalRecordExample.createCriteria().andRequestIdEqualTo(Integer.parseInt(requestId));
		//approvalRecordExample.setOrderByClause("create_time desc");
		//List<ApprovalRecord> approvalRecordList=approvalRecordDao.selectByExample(approvalRecordExample);
		//if (approvalRecordList.size()>0) {
			//ApprovalRecord approvalRecord=approvalRecordList.get(0);
			//判断是不是HR驳回
			//if (approvalRecord.getRoleId()==null) {
				//List<ApprovalRecordBean> approvalRecordBeanList = ApprovalRecordExtDao.getApprovalRecordInfoByHR(Integer.parseInt(requestId));
				//return approvalRecordBeanList;
			//}
		//}
		
		/*//获取申请记录
		Request request=requestDao.selectByPrimaryKey(Integer.parseInt(requestId));
		//获取roleId
		Integer requestRoleId=request.getRoleId();
		//获取审批规则
		Integer approvalRuleId=request.getApprovalRuleId();
		ApprovalRule approvalRule=approvalRuleDao.selectByPrimaryKey(approvalRuleId);
		Integer lowestApprovalRoleLevel=null;
		if (approvalRule.getLowestApprovalRole()!=null) {
			lowestApprovalRoleLevel=approvalRule.getLowestApprovalRole();
		}
		List<Integer> roleLevelList=new ArrayList<>();
		if (approvalRule.getOneApprovalRole()!=null) {
			roleLevelList.add(approvalRule.getOneApprovalRole());
			if (approvalRule.getTwoApprovalRole()!=null) {
				roleLevelList.add(approvalRule.getTwoApprovalRole());
				if (approvalRule.getThreeApprovalRole()!=null) {
					roleLevelList.add(approvalRule.getThreeApprovalRole());
					if (approvalRule.getFourApprovalRole()!=null) {
						roleLevelList.add(approvalRule.getFourApprovalRole());
						if (approvalRule.getFiveApprovalRole()!=null) {
							roleLevelList.add(approvalRule.getFiveApprovalRole());
						}
					}
				}
			}
		}
		Integer nextApprovalRoleLevel=roleLevelList.get(0);
		//去DB里查的roleID集合
		List<Integer> roleIdDBList=new ArrayList<>();
		*//**
		 * 获取roleList 岗位集合
		 *//*
		Role requestRole=roleDao.selectByPrimaryKey(requestRoleId);
		
		
		String rolePath=requestRole.getRolePath();
		String[] roleIds = reverseArray(rolePath.split("-"));
		List<Integer> roleIdList = new ArrayList<Integer>();
		for (String roleid : roleIds) {
			if(StringUtils.isEmpty(roleid)){
				continue;
			}
			Integer intRoleId = Integer.parseInt(roleid);
			//跳过岗位本身
			if(intRoleId == requestRole.getRoleId().intValue()){
				continue;
			}
			// 取N+1岗位id
			if (nextApprovalRoleLevel == 99) {
				if(haveEmployeeInRole(intRoleId)){
					Role nextRole = roleDao.selectByPrimaryKey(intRoleId);
					//判断最低审批级别
					if(lowestApprovalRoleLevel  == null || lowestApprovalRoleLevel<= nextRole.getRoleLevel()){
						roleIdDBList.add(intRoleId);
						List<ApprovalRecordBean> approvalRecordBeanList = ApprovalRecordExtDao.getApprovalRecordInfoById(Integer.parseInt(requestId), roleIdDBList, new Date());
						return approvalRecordBeanList;
					}else{
						continue;
					}
				}else{
					//空岗位跳过
					continue;
				}
			}else{
				roleIdList.add(intRoleId);	
			}
		}
		// create example
		RoleExample roleExample=new RoleExample();
		roleExample.createCriteria().andRoleIdIn(roleIdList);
		roleExample.setOrderByClause("role_level asc");
		List<Role> roleList = roleDao.selectByExample(roleExample);
		//如果审批流中取得的岗位都为空，直接去取本人的父级岗位人审批
		if (roleList.size()==0) {
			Role nextRole=this.getNextApprovalRoleId(requestRole, nextApprovalRoleLevel, lowestApprovalRoleLevel);
			roleIdDBList.add(nextRole.getRoleId());
			List<ApprovalRecordBean> approvalRecordBeanList= ApprovalRecordExtDao.getApprovalRecordInfoById(Integer.parseInt(requestId), roleIdDBList, new Date());
			return approvalRecordBeanList;
		}
		List<Integer> roleIdListNeed=new ArrayList<>();
		for (int i=0;i<roleLevelList.size();i++) {
			for (Role role : roleList) {
				if(roleLevelList.get(i)==role.getRoleLevel()){
					// roleid add list
					roleIdListNeed.add(role.getRoleId());
				}
			}
		}
		//规则的最终审批人在此人的rolePath中不存在时
		boolean isLevel = true;
		for (Role role : roleList) {
			if(roleLevelList.get(roleLevelList.size()-1)==role.getRoleLevel()){
				isLevel=false;
				break;
			}
		}
		if (isLevel) {
			Integer roleId=null;
			for (Role role : roleList) {
				if(role.getRoleLevel()>roleLevelList.get(roleLevelList.size()-1)){
					roleId=role.getRoleId();
					break;
				}
			}
			roleIdListNeed.add(roleId);
		}
		
		for (Integer roleId : roleIdListNeed) {
			//判断空岗位，如果不是空岗位，取下面的人
			//如果是空岗位，跳过本行（如果是最后一个岗位，找nextrole-for）
			if(haveEmployeeInRole(roleId)){
				roleIdDBList.add(roleId);
			}else{
				//如果是最后一个岗位，找nextrole-for
				if (roleId==roleIdListNeed.get(roleIdListNeed.size()-1)) {
					//rolePath的ID集合
					for (Integer nextRoleId : roleIdList) {
						Role nextRole=roleDao.selectByPrimaryKey(nextRoleId);
						Role emptyRole=roleDao.selectByPrimaryKey(roleId);
						if (nextRole.getRoleLevel() > emptyRole.getRoleLevel()) {
							if (haveEmployeeInRole(nextRoleId)) {
								roleIdDBList.add(nextRoleId);
								break;
							}
						}
					}
				}
				//空岗位跳过
				continue;
			}
		}
		//sql
		List<ApprovalRecordBean> approvalRecordBeanList= ApprovalRecordExtDao.getApprovalRecordInfoById(Integer.parseInt(requestId), roleIdDBList, new Date());
		return approvalRecordBeanList;*/
	}
	/**
	 * 获取补签结果
	 */
	@Override
	public List<ApprovalRecordBean> getApprovalRecordById(Integer retroactiveId) {
		List<ApprovalRecordBean> approvalRecordBeanList=ApprovalRecordExtDao.getApprovalRecordById(retroactiveId);
		//查询审批节点人员 2018-10-12
		/*List<ApprovalRecordBean> approvalRecordBeanList=ApprovalRecordExtDao.getApprovalRecordById(retroactiveId);
		for (ApprovalRecordBean approvalRecordBean : approvalRecordBeanList) {
			if (approvalRecordBean.getChineseName()==null) {
				Integer roleId=approvalRecordBean.getRoleId();
				EmployeeRoleExample example=new EmployeeRoleExample();
				example.or().andRoleIdEqualTo(roleId).andThruDateIsNull();
				example.or().andRoleIdEqualTo(roleId).andThruDateGreaterThanOrEqualTo(new Date());
				List<EmployeeRole> employeeRoleList=employeeRoleDao.selectByExample(example);
				List<Integer> employeeIdList=new ArrayList<>();
				for (EmployeeRole employeeRole : employeeRoleList) {
					employeeIdList.add(employeeRole.getEmployeeId());
				}
				List<String> employeeNameList=new ArrayList<>();
				if(employeeIdList == null || employeeIdList.size()==0){
					employeeNameList.add("无后续审批人，该流程无法流转！");
				}else{
					EmployeeExample employeeExample=new EmployeeExample();
					employeeExample.createCriteria().andEmployeeIdIn(employeeIdList);
					List<Employee> employeeList=employeeDao.selectByExample(employeeExample);
					String email = null;
					String ids = null;
					for (Employee employee : employeeList) {
						employeeNameList.add(employee.getChineseName());
						if (email==null) {
							email = employee.getEmail();
							ids = Integer.toString(employee.getEmployeeId());
						} else {
							email = email +","+ employee.getEmail();
							ids = ids +","+ employee.getEmployeeId();
						}
					}
					approvalRecordBean.setEmail(email);
					approvalRecordBean.setApproverIds(ids);
				}
				approvalRecordBean.setEmployeeNameList(employeeNameList);
			}
		}*/
		return approvalRecordBeanList;
	}

	/**
	 * 获取多条补签结果
	 */
	@Override
	public List<ApprovalRecordBean> getApprovalRecordByAttendanceId(Integer attendanceId) {
		List<ApprovalRecordBean> recordlist=new ArrayList<ApprovalRecordBean>();
		RetroactiveExample retroactiveExample=new RetroactiveExample();
		retroactiveExample.createCriteria().andAttendanceIdEqualTo(attendanceId);
		List<Retroactive> retroactiveList=retroactiveDao.selectByExample(retroactiveExample);
		if (retroactiveList.size()>0) {
			for(int i=0;i<retroactiveList.size();i++) {
				List<ApprovalRecordBean> approvalRecordBeanList=this.getApprovalRecordById(retroactiveList.get(i).getRetroactiveId());
				for(int j=0;j<approvalRecordBeanList.size();j++) {
					recordlist.add(approvalRecordBeanList.get(j));
				}
			}
		}
		return recordlist;
	}
	
	/**
	 * 计算请假/加班时长
	 */
	public Integer getRequestMinutes(Request request){
		return saveOrGetRequestMinutes(request,0);
	}
	
	/**
	 *计算加班时长（分钟）
	 */
	private Integer getOverTimeMinutes(Request request,Integer approveStatus){
		
		//开始日期
		Date startDate = request.getStartDate();
		//结束日期
		Date endDate = request.getEndDate();
		
		//时间简单判断
		if(TimeUtils.getMinutes(request.getStartDate(), request.getStartTime(), request.getEndDate(), request.getEndTime())>1440){
			//加班申请时长不能超过24小时
			throw new ResultFaultException("4_00012");
		}
		
		Integer resultMinutes =0;
		
		//取得当天的考勤数据
		String[] attTimes = getActAttendance(startDate,request.getEmployeeId());
		if(attTimes==null){
			throw new ResultFaultException("4_00017");
		}
		String stime = attTimes[0];
		String etime = attTimes[1];
		if(StringUtils.isEmpty(stime) && !StringUtils.isEmpty(etime)){
			//考勤信息不完整
			throw new ResultFaultException("4_00014"); 
		}
		if(!StringUtils.isEmpty(stime) && StringUtils.isEmpty(etime)){
			//考勤信息不完整
			throw new ResultFaultException("4_00014"); 
		}
		if(StringUtils.isEmpty(stime) && StringUtils.isEmpty(etime)){
			throw new ResultFaultException("4_00017");
		}

		//判断考勤跨天
		boolean oneday = true;
		if(startDate.before(endDate)){
			oneday = false;
		}	
		
		if(oneday){
			
			//取得人员的排班时间
			EmployeeSchedulExample employeeSchedulExample = new EmployeeSchedulExample();
			employeeSchedulExample.or().andEmployeeIdEqualTo(request.getEmployeeId()).andFromDateLessThanOrEqualTo(startDate).andThruDateGreaterThanOrEqualTo(startDate);
			employeeSchedulExample.or().andEmployeeIdEqualTo(request.getEmployeeId()).andFromDateLessThanOrEqualTo(startDate).andThruDateIsNull();
			employeeSchedulExample.setOrderByClause("from_date Desc");
			List<EmployeeSchedul> employeeSchedulList = employeeSchedulDao.selectByExample(employeeSchedulExample);
			if(employeeSchedulList==null || employeeSchedulList.size()==0){
				//未找到排班信息
				throw new ResultFaultException("5_00006"); 
			}
			
			//取得打卡时间配置记录
			PunchTime punchTime = punchTimeDao.selectByPrimaryKey(employeeSchedulList.get(0).getPunchTimeId());
			//取得应出勤时长
			Integer punchMinutes = TimeUtils.differMinutes(punchTime.getStartFromTime(), punchTime.getEndFromTime());
			//平时加班要判断加班扣除时间点
			String beginTime = this.getOverTime(startDate);
			
			//申请时间和打卡时间取交集
			String resStartTime = stime;
			String resEndTime = etime;
			if(TimeUtils.compareTime(stime, request.getStartTime())<0){
				resStartTime = request.getStartTime();
			}
			if(TimeUtils.compareTime(stime, etime)>0 && TimeUtils.compareTime(request.getStartTime(), request.getEndTime())<=0){
				resEndTime = request.getEndTime();
			}
			if(TimeUtils.compareTime(stime, etime)<0 && TimeUtils.compareTime(request.getStartTime(), request.getEndTime())<0){
				if(TimeUtils.compareTime(etime, request.getEndTime())>0){
					resEndTime = request.getEndTime();
				}
			}
			
			//判断是否是休息日
			SchedulDayExample sdExample = new SchedulDayExample();
			sdExample.createCriteria().andSdDateEqualTo(startDate).andSwIdEqualTo(employeeSchedulList.get(0).getSwId());
			List<SchedulDayKey> schedulDayList = schedulDayDao.selectByExample(sdExample);
			//如果没查到数据，证明是休息日加班。
			if(schedulDayList == null || schedulDayList.size()==0){
				//节假日加班
				if (request.getOvertimeInterval() == null) {
					resultMinutes = TimeUtils.differMinutes(resStartTime, resEndTime);
				} else {
					resultMinutes = TimeUtils.differMinutes(resStartTime, resEndTime) - request.getOvertimeInterval();
				}
				updateRequestReport(request,approveStatus,startDate,new BigDecimal(resultMinutes),1);
				return resultMinutes;
			}
				
			//平时加班
			String accEndTime = getAttendanceEndTime(startDate,request.getEmployeeId());
			if(StringUtils.isEmpty(accEndTime)){
				throw new ResultFaultException("4_00017");
			}
			if(TimeUtils.compareTime(accEndTime, resStartTime)>0){
				throw new ResultFaultException("4_00009");
			}
			if(TimeUtils.compareTime(accEndTime, resStartTime)<0){
				accEndTime = resStartTime;
			}
			if(TimeUtils.compareTime(accEndTime, beginTime)<0 && TimeUtils.compareTime(resEndTime, beginTime)>=0){
				resultMinutes = TimeUtils.differMinutes(accEndTime, resEndTime) - 30;
			}else{
				resultMinutes = TimeUtils.differMinutes(accEndTime, resEndTime);
			}
			
			updateRequestReport(request,approveStatus,startDate,new BigDecimal(resultMinutes),3);
			return resultMinutes;
		}else{
			//跨天

			//取得人员的排班时间
			EmployeeSchedulExample employeeSchedulExample = new EmployeeSchedulExample();
			employeeSchedulExample.or().andEmployeeIdEqualTo(request.getEmployeeId()).andFromDateLessThanOrEqualTo(startDate).andThruDateGreaterThanOrEqualTo(startDate);
			employeeSchedulExample.or().andEmployeeIdEqualTo(request.getEmployeeId()).andFromDateLessThanOrEqualTo(startDate).andThruDateIsNull();
			employeeSchedulExample.setOrderByClause("from_date desc");
			List<EmployeeSchedul> employeeSchedulList = employeeSchedulDao.selectByExample(employeeSchedulExample);
			if(employeeSchedulList==null || employeeSchedulList.size()==0){
				//未找到排班信息
				throw new ResultFaultException("5_00006"); 
			}

			//取得打卡时间配置记录
			PunchTime punchTime = punchTimeDao.selectByPrimaryKey(employeeSchedulList.get(0).getPunchTimeId());
			//取得应出勤时长
			Integer punchMinutes = TimeUtils.differMinutes(punchTime.getStartFromTime(), punchTime.getEndFromTime());
			//平时加班要判断加班扣除时间点
			String beginTime = this.getOverTime(startDate);
			
			//申请时间和打卡时间取交集
			String resStartTime = stime;
			String resEndTime = etime;
			if(TimeUtils.compareTime(stime, request.getStartTime())<0){
				resStartTime = request.getStartTime();
			}
			if(TimeUtils.compareTime(etime, request.getEndTime())>0){
				resEndTime = request.getEndTime();
			}
			
			//判断是否是休息日
			SchedulDayExample sdExample = new SchedulDayExample();
			sdExample.createCriteria().andSdDateEqualTo(startDate).andSwIdEqualTo(employeeSchedulList.get(0).getSwId());
			List<SchedulDayKey> schedulDayList = schedulDayDao.selectByExample(sdExample);
			if(schedulDayList==null || schedulDayList.size()==0){
				//节假日加班
				if (request.getOvertimeInterval()==null) {
					resultMinutes = TimeUtils.getMinutes(startDate, resStartTime, endDate, resEndTime);
				} else {
					resultMinutes = TimeUtils.getMinutes(startDate, resStartTime, endDate, resEndTime) - request.getOvertimeInterval();
				}
				updateRequestReport(request,approveStatus,startDate,new BigDecimal(resultMinutes),1);
				return resultMinutes;
			}
			
			//平时加班
			String accEndTime = getAttendanceEndTime(startDate,request.getEmployeeId());
			if(StringUtils.isEmpty(accEndTime)){
				throw new ResultFaultException("4_00017");
			}
			if(TimeUtils.compareTime(accEndTime, resStartTime)>0){
				throw new ResultFaultException("4_00009");
			}
			if(TimeUtils.compareTime(accEndTime, resStartTime)<0){
				accEndTime = resStartTime;
			}
			
			if(TimeUtils.compareTime(accEndTime, beginTime)<0){
				resultMinutes = TimeUtils.getMinutes(startDate, accEndTime, endDate, resEndTime)-30;
			}else{
				resultMinutes = TimeUtils.getMinutes(startDate, accEndTime, endDate, resEndTime);
			}
			updateRequestReport(request,approveStatus,startDate,new BigDecimal(resultMinutes),3);
			return resultMinutes;
		}
	}

	/**
	 * 计算请假时长（小时，两位小数）--张鑫
	 */
	@Override
	public Integer getRequestMinutes(RequestBean requestBean) {
		Request request=new Request();
		request.setStartDate(requestBean.getStartDate());
		request.setEndDate(requestBean.getEndDate());
		request.setStartTime(requestBean.getStartTime());
		request.setEndTime(requestBean.getEndTime());
		request.setEmployeeId(requestBean.getEmployeeId());
		request.setStartToTime(requestBean.getStartToTime());
		request.setRequestType(requestBean.getRequestType());
		Integer resultMinutes=this.getRequestMinutes(request);
		return resultMinutes;
	}

	/**
	 * 根据夏令冬令时间切换加班时间
	 * 
	 * @param date
	 * @return
	 */
	public String getOverTime(Date date) {
		SystemConfigureExample systemConfigureExample = new SystemConfigureExample();
		List<SystemConfigure> systemConfigures = systemConfigureDao.selectByExample(systemConfigureExample);
		if (systemConfigures == null || systemConfigures.size()==0) {
			throw new ResultFaultException("0_00030");
		}
		SystemConfigure sysconfig = systemConfigures.get(0);
		Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int month = calendar.get(Calendar.MONTH);
		if (month>=4 && month<=9) {
			return sysconfig.getOverAfterTime();
		} else {
			return sysconfig.getOverBeforeTime();
		}
	}
	
	/**
	 * 计算请假/加班时长
	 * 更新统计用的申请时长基础表
	 * 2：审批通过，插入数据；3：审批拒绝，删除数据
	 */
	private Integer saveOrGetRequestMinutes(Request request,Integer approveStatus){
		
		//时间简单判断
		if(request.getRequestType()==3 || request.getRequestType()==4 || request.getRequestType()==11){
			//正常
		} else {
			if(TimeUtils.compareDateTime(request.getStartDate(), request.getStartTime(), request.getEndDate(), request.getEndTime())>=0){
				//结束时间必须大于开始时间
				throw new ResultFaultException("4_00018");
			}
		}
		
		//加班的情况
		if(request.getRequestType()==7){
			//
			if (request.getOvertimeType() != null && request.getOvertimeType() == 4) {//早上加班
				updateRequestReport(request,approveStatus,request.getStartDate(),request.getHours(),3);
				return request.getHours().intValue();
			} else {
				return getOverTimeMinutes(request,approveStatus);
			}
		}

		//计算时，是否考虑休息日
		boolean includeWeekDay = false;
		if(request.getRequestType()==0 
				|| request.getRequestType()==1
				|| request.getRequestType()==5
				|| request.getRequestType()==6){//事假、年假、病假
			includeWeekDay = true;
		}
		
		//按天计算
		boolean isByDay = false;
		if(request.getRequestType()==3 || request.getRequestType()==4 || request.getRequestType()==11 || request.getRequestType()==13){
			isByDay = true;
		}
		
		//开始日期
		Date startDate = request.getStartDate();
		//结束日期
		Date endDate = request.getEndDate();
		
		//按天计算的情况
		if(isByDay){
			//控制循环用的
			int resultDay=0;
			Date tempDate = DateUtils.addDays(startDate, -1);
			while (tempDate.compareTo(endDate) < 0) {
				tempDate = DateUtils.addDays(tempDate, 1);
				resultDay = resultDay + 1;
				updateRequestReport(request,approveStatus,tempDate,new BigDecimal(1),3);
			}
			return resultDay;
		}
		
		Integer resultMinutes = 0;
		if(startDate.compareTo(endDate)==0){
			//一天内的请假
			//取得人员的排班时间
			EmployeeSchedulExample employeeSchedulExample = new EmployeeSchedulExample();
			employeeSchedulExample.or().andEmployeeIdEqualTo(request.getEmployeeId()).andFromDateLessThanOrEqualTo(startDate).andThruDateGreaterThanOrEqualTo(startDate);
			employeeSchedulExample.or().andEmployeeIdEqualTo(request.getEmployeeId()).andFromDateLessThanOrEqualTo(startDate).andThruDateIsNull();
			employeeSchedulExample.setOrderByClause("from_date Desc");
			List<EmployeeSchedul> employeeSchedulList = employeeSchedulDao.selectByExample(employeeSchedulExample);
			if(employeeSchedulList==null || employeeSchedulList.size()==0){
				//未找到排班信息
				throw new ResultFaultException("5_00006"); 
			}
			
			//考虑休息日的情况
			if(includeWeekDay){
				SchedulDayExample sdExample = new SchedulDayExample();
				sdExample.createCriteria().andSdDateEqualTo(startDate).andSwIdEqualTo(employeeSchedulList.get(0).getSwId());
				List<SchedulDayKey> schedulDayList = schedulDayDao.selectByExample(sdExample);
				//如果没查到数据，证明不上班。
				if(schedulDayList == null || schedulDayList.size()==0){
					return 0;
				}
			}
			//取得当天的考勤数据
			Attendance attendance = null;
			AttendanceExample attendanceExample = new AttendanceExample();
			AttendanceExample.Criteria attendanceCriteria = attendanceExample.createCriteria();
			attendanceCriteria.andAttendanceDateEqualTo(startDate);
			attendanceCriteria.andEmployeeIdEqualTo(request.getEmployeeId());
			List<Attendance> attendanceList = attendanceDao.selectByExample(attendanceExample);
			if(attendanceList != null && attendanceList.size()>0){
				attendance = attendanceList.get(0);
				if(StringUtils.isEmpty(attendance.getStartTime())){
					attendance =null;
				}
			}
			
			//取得打卡时间配置记录
			PunchTime punchTime = punchTimeDao.selectByPrimaryKey(employeeSchedulList.get(0).getPunchTimeId());
			//取得午休时长
			Integer restMinutes = 0;
			if (punchTime.getRestFromTime()!=null && punchTime.getRestToTime()!=null) {
				restMinutes = TimeUtils.differMinutes(punchTime.getRestFromTime(), punchTime.getRestToTime());
			}
//			Integer restMinutes = TimeUtils.differMinutes(punchTime.getRestFromTime(), punchTime.getRestToTime());
			//取得应出勤时长
			Integer punchMinutes = TimeUtils.differMinutes(punchTime.getStartFromTime(), punchTime.getEndFromTime());
			
			String requestStartTime = request.getStartTime();
			String requestEndTime = request.getEndTime();
			
			if(TimeUtils.compareTime(requestStartTime, punchTime.getStartFromTime())<0){
				requestStartTime = punchTime.getStartFromTime();
			}
			if(TimeUtils.compareTime(requestEndTime, punchTime.getEndToTime())>0){
				requestEndTime = punchTime.getEndToTime();
			}
			
			if(attendance!=null){
				String attendanceStartTime = attendance.getStartTime();
				if(TimeUtils.compareTime(attendanceStartTime, punchTime.getStartFromTime())<0){
					attendanceStartTime = punchTime.getStartFromTime();
				}
				//计算出的下班时间
				String etime = TimeUtils.getEndTime(attendanceStartTime, punchMinutes);
				if(TimeUtils.compareTime(requestEndTime, etime)>0){
//					requestEndTime = etime;
				}
			}else{
				//计算出的下班时间
				String etime = TimeUtils.getEndTime(requestStartTime, punchMinutes);
				if(TimeUtils.compareTime(requestEndTime, etime)>0){
					requestEndTime = etime;
				}
			}

			resultMinutes = getMinutesRemoveRest(requestStartTime,requestEndTime,punchTime);
			if(resultMinutes>punchMinutes-restMinutes){
				resultMinutes = punchMinutes-restMinutes;
			}
			//时间统计基础记录
			updateRequestReport(request,approveStatus,startDate,new BigDecimal(resultMinutes),3);
			
		}else{
			//跨天
		
			//控制循环用的
			Date tempDate = DateUtils.addDays(new Date(startDate.getTime()), -1);

			while (tempDate.compareTo(endDate) < 0) {
				tempDate = DateUtils.addDays(tempDate, 1);
				//取得人员的排班时间
				EmployeeSchedulExample employeeSchedulExample = new EmployeeSchedulExample();
				employeeSchedulExample.or().andEmployeeIdEqualTo(request.getEmployeeId()).andFromDateLessThanOrEqualTo(tempDate).andThruDateGreaterThanOrEqualTo(tempDate);
				employeeSchedulExample.or().andEmployeeIdEqualTo(request.getEmployeeId()).andFromDateLessThanOrEqualTo(tempDate).andThruDateIsNull();
				employeeSchedulExample.setOrderByClause("from_date desc");
				List<EmployeeSchedul> employeeSchedulList = employeeSchedulDao.selectByExample(employeeSchedulExample);
				if(employeeSchedulList==null || employeeSchedulList.size()==0){
					//未找到排班信息
					throw new ResultFaultException("5_00006"); 
				}
				
				//考虑休息日的情况
				if(includeWeekDay){
					SchedulDayExample sdExample = new SchedulDayExample();
					sdExample.createCriteria().andSdDateEqualTo(tempDate).andSwIdEqualTo(employeeSchedulList.get(0).getSwId());
					List<SchedulDayKey> schedulDayList = schedulDayDao.selectByExample(sdExample);
					//如果没查到数据，证明不上班。
					if(schedulDayList == null || schedulDayList.size()==0){
						continue;
					}
				}
				
				//取得打卡时间配置记录
				PunchTime punchTime = punchTimeDao.selectByPrimaryKey(employeeSchedulList.get(0).getPunchTimeId());
				//取得午休时长
				Integer restMinutes = 0;
				if (punchTime.getRestFromTime()!=null && punchTime.getRestToTime()!=null) {
					restMinutes = TimeUtils.differMinutes(punchTime.getRestFromTime(), punchTime.getRestToTime());
				}
//				Integer restMinutes = TimeUtils.differMinutes(punchTime.getRestFromTime(), punchTime.getRestToTime());
				//取得应出勤时长
				Integer punchMinutes = TimeUtils.differMinutes(punchTime.getStartFromTime(), punchTime.getEndFromTime());
							
				//第一天时长计算
				if(tempDate.compareTo(startDate)==0){
					
					//取得当天的考勤数据
					Attendance attendance = null;
					AttendanceExample attendanceExample = new AttendanceExample();
					AttendanceExample.Criteria attendanceCriteria = attendanceExample.createCriteria();
					attendanceCriteria.andAttendanceDateEqualTo(tempDate);
					attendanceCriteria.andEmployeeIdEqualTo(request.getEmployeeId());
					List<Attendance> attendanceList = attendanceDao.selectByExample(attendanceExample);
					if(attendanceList != null && attendanceList.size()>0){
						attendance = attendanceList.get(0);
						if(StringUtils.isEmpty(attendance.getStartTime())){
							attendance =null;
						}
					}
					
					String stime = request.getStartTime();
					String etime = request.getStartToTime();
					
					//根据应出勤时间计算
					if(TimeUtils.compareTime(stime, punchTime.getStartFromTime())<0){
						stime = punchTime.getStartFromTime();
					}

					//存在打卡记录
					if(attendance!=null){
						//计算当天的应签退时间
						String attendanceStartTime = attendance.getStartTime();
						if(TimeUtils.compareTime(attendanceStartTime, punchTime.getStartFromTime())<0){
							attendanceStartTime = punchTime.getStartFromTime();
						}
						etime = TimeUtils.getEndTime(attendanceStartTime, punchMinutes);
						if(TimeUtils.compareTime(etime, punchTime.getEndToTime())>0){
							etime = punchTime.getEndToTime();
						}
					}else{
						if(!StringUtils.isEmpty(etime)){
							if(TimeUtils.compareTime(etime, punchTime.getEndToTime())>0 ){
								etime = punchTime.getEndToTime();
							}
						}else{
							etime = punchTime.getEndToTime();
						}
					}

					//考虑午休的情况
					resultMinutes = getMinutesRemoveRest(stime,etime,punchTime);
					if(resultMinutes>punchMinutes-restMinutes){
						resultMinutes = punchMinutes-restMinutes;
					}

					//时间统计基础记录
					updateRequestReport(request,approveStatus,tempDate,new BigDecimal(resultMinutes),3);
				}
				//中间天的时长
				if(tempDate.compareTo(startDate) != 0 && tempDate.compareTo(endDate) != 0){
					//考虑午休的情况
					Integer tempMinutes = punchMinutes-restMinutes;
					//时间统计基础记录
					updateRequestReport(request,approveStatus,tempDate,new BigDecimal(tempMinutes),3);
					resultMinutes += tempMinutes;
				}
				//最后一天的时长
				if(tempDate.compareTo(endDate) == 0){
					
					//配置的开始时间作为当天开始时间
					String stime = punchTime.getStartFromTime();
					String etime = request.getEndTime();
					if(TimeUtils.compareTime(stime, etime)>=0){
						//没到工作时间
						continue;
					}
					if(TimeUtils.compareTime(etime, punchTime.getEndFromTime())>=0 ){
						etime = punchTime.getEndFromTime();
					}

					//考虑午休的情况
					Integer tempMinutes = getMinutesRemoveRest(stime,etime,punchTime);
					if(tempMinutes>punchMinutes-restMinutes){
						tempMinutes = punchMinutes-restMinutes;
					}

					//时间统计基础记录
					updateRequestReport(request,approveStatus,tempDate,new BigDecimal(tempMinutes),3);
					resultMinutes += tempMinutes;
				}
			}
		}
		return resultMinutes;
	}
	
	/**
	 * 更新报表计算用的数据
	 * @param request
	 * @param approveStatus
	 * @param curDate
	 * @param resultMinutes
	 */
	private void updateRequestReport(Request request,Integer approveStatus,Date curDate,BigDecimal resultMinutes,Integer overType){
		//时间统计基础记录
		if(approveStatus == 2){
			//判断当天是不是节假日
			int dayType=3;//平时加班
			if(overType ==3){
				dayType = overType;
			}else{
				HolidayExample holidayExample = new HolidayExample();
				holidayExample.createCriteria().andHolidayDateEqualTo(curDate);
				List<Holiday> holidayList = holidayDao.selectByExample(holidayExample);
				if(holidayList == null || holidayList.size()==0){
					dayType =2;//周末加班
				}else{
					Holiday ho = holidayList.get(0);
					if(ho.getIsLegal()==1){
						dayType = 1;//法定加班
					}else{
						dayType = 2;//周末加班
					}
				}
			}
			RequestReport requestReport = new RequestReport();
			requestReport.setCreateTime(new Date());
			requestReport.setEmployeeId(request.getEmployeeId());
			requestReport.setHours(resultMinutes);
			requestReport.setReportType(request.getRequestType());
			if(request.getRequestType() == 7){
				requestReport.setOvertimeType(dayType);
				if (request.getOvertimeType() == 4) {//早上加班
					requestReport.setOvertimeType(4);
				}
			}
			if(request.getRequestType() == 1){//年假添加年份
				requestReport.setReportYear(request.getReportYear());
			}
			requestReport.setRequestId(request.getRequestId());
			requestReport.setRequestReportDate(curDate);
			requestReport.setUpdateTime(new Date());
			requestReportDao.insertSelective(requestReport);
		}
		if(approveStatus == 3){
			RequestReportExample requestReportExample = new RequestReportExample();
			requestReportExample.createCriteria().andRequestIdEqualTo(request.getRequestId()).andRequestReportDateEqualTo(curDate);
			requestReportDao.deleteByExample(requestReportExample);
		}
	}
	
	/**
	 * 重新计算考勤状态 
	 * @param curDate
	 * @param employeeId
	 */
	@Override
	public void resetAttendance(Date startDate,Date endDate, List<Integer> employeeIdList){
		//取出包含当天的申请（不包含补签和加班申请）
		List<Integer> requestTypeList = new ArrayList<Integer>(); 
		requestTypeList.add(0);
		requestTypeList.add(1);
		requestTypeList.add(2);
		requestTypeList.add(3);
		requestTypeList.add(4);
		requestTypeList.add(5);
		requestTypeList.add(6);
		requestTypeList.add(8);
		requestTypeList.add(9);
		requestTypeList.add(11);
		requestTypeList.add(12);
		requestTypeList.add(13);
		
		List<Employee> employeeList = new ArrayList<Employee>();
		//如果employeeIdList为空，取全员信息
		if(employeeIdList==null || employeeIdList.size()==0){
			EmployeeExample employeeExample = new EmployeeExample();
			employeeExample.or().andFromDateLessThanOrEqualTo(endDate).andThruDateIsNull();
			employeeExample.or().andFromDateLessThanOrEqualTo(endDate).andThruDateGreaterThanOrEqualTo(startDate);
			employeeList = employeeDao.selectByExample(employeeExample);
			employeeIdList=new ArrayList<Integer>();
			for(int i=0;i<employeeList.size();i++){
				employeeIdList.add(employeeList.get(i).getEmployeeId());
			}
		}else{
			EmployeeExample employeeExample = new EmployeeExample();
			employeeExample.createCriteria().andEmployeeIdIn(employeeIdList);
			employeeList = employeeDao.selectByExample(employeeExample);
		}
		
		//查询历史申请
		RequestBean requestBean=new RequestBean();
		requestBean.setStartDate(startDate);
		requestBean.setEndDate(endDate);
		requestBean.setEmployeeIdList(employeeIdList);
		requestBean.setRequestTypeList(requestTypeList);
		requestBean.setApprovalState(2);
		List<Request> requestList = requestExtDao.getRequestByApprovalState(requestBean);
		
		//取得申请通过的补签
		RetroactiveBean retroactiveBean=new RetroactiveBean();
		retroactiveBean.setEmployeeIdList(employeeIdList);
		retroactiveBean.setAttendanceDateStart(startDate);
		retroactiveBean.setAttendanceDateEnd(endDate);
		retroactiveBean.setApprovalState(2);
		List<Retroactive> retroactiveList =retroactiveExtDao.getRetroactiveByApprovalState(retroactiveBean);
		
		//获取特殊情况
		EmployeeSpecialBean employeeSpecialBean=new EmployeeSpecialBean();
		employeeSpecialBean.setEmployeeIdList(employeeIdList);
		employeeSpecialBean.setStartDate(startDate);
		employeeSpecialBean.setEndDate(endDate);
		List<EmployeeSpecialKey> employeeSpecialKeyList=employeeSpecialExtDao.selectByEmployeeSpecialBean(employeeSpecialBean);
		
		//查询全部考勤打卡时间
		List<PunchTime> punchTimeList = punchTimeDao.selectByExample(new PunchTimeExample());
		Map<Integer, PunchTime> punchTimeMap = new HashMap<Integer, PunchTime>();	
		for(int pi=0;pi<punchTimeList.size();pi++){
			punchTimeMap.put(punchTimeList.get(pi).getPunchTimeId(), punchTimeList.get(pi));
		}
		
		//查询特殊情况信息
		SpecialExample specialExample=new SpecialExample();
		specialExample.createCriteria()
		.andSpecialDateBetween(startDate,endDate);
		List<Special> specialSList=specialDao.selectByExample(specialExample);
		Map<Integer, Special> specialMap = new HashMap<Integer, Special>();
		for(int si=0;si<specialSList.size();si++){
			specialMap.put(specialSList.get(si).getSpecialId(), specialSList.get(si));
		}
		
		//取得人员的排班时间
		EmployeeSchedulExample employeeSchedulExample = new EmployeeSchedulExample();
		employeeSchedulExample.createCriteria().andEmployeeIdIn(employeeIdList);
		employeeSchedulExample.setOrderByClause("from_date desc");
		List<EmployeeSchedul> employeeSchedulDataList = employeeSchedulDao.selectByExample(employeeSchedulExample);
		List<Integer> swIdList = new ArrayList<Integer>();
		Map<Integer, List<EmployeeSchedul>> employeeSchedulMap = new HashMap<Integer, List<EmployeeSchedul>>();
		for (int ei = 0; ei < employeeSchedulDataList.size(); ei++) {
			if (employeeSchedulMap.containsKey(employeeSchedulDataList.get(ei).getEmployeeId())) {
				List<EmployeeSchedul> eList = employeeSchedulMap.get(employeeSchedulDataList.get(ei).getEmployeeId());
				eList.add(employeeSchedulDataList.get(ei));
				employeeSchedulMap.put(employeeSchedulDataList.get(ei).getEmployeeId(), eList);
			} else {
				List<EmployeeSchedul> eList = new ArrayList<EmployeeSchedul>();
				eList.add(employeeSchedulDataList.get(ei));
				employeeSchedulMap.put(employeeSchedulDataList.get(ei).getEmployeeId(), eList);
			}
			boolean swType=true;
			for(int si=0;si<swIdList.size();si++){
				if(swIdList.get(si).equals(employeeSchedulDataList.get(ei).getSwId())){
					swType=false;
					break;
				}
			}
			if(swType){
				swIdList.add(employeeSchedulDataList.get(ei).getSwId());
			}
		}
		
		// 查询班次日期
		SchedulDayExample schedulDayExample = new SchedulDayExample();
		schedulDayExample.createCriteria().andSwIdIn(swIdList);
		List<SchedulDayKey> schedulDayKeyList = schedulDayDao.selectByExample(schedulDayExample);
		Map<Integer, List<SchedulDayKey>> schedulDayKeyMap = new HashMap<Integer, List<SchedulDayKey>>();
		for (int si = 0; si < schedulDayKeyList.size(); si++) {
			if (schedulDayKeyMap.containsKey(schedulDayKeyList.get(si).getSwId())) {
				List<SchedulDayKey> lList = schedulDayKeyMap.get(schedulDayKeyList.get(si).getSwId());
				lList.add(schedulDayKeyList.get(si));
				schedulDayKeyMap.put(schedulDayKeyList.get(si).getSwId(), lList);
			} else {
				List<SchedulDayKey> lList = new ArrayList<SchedulDayKey>();
				lList.add(schedulDayKeyList.get(si));
				schedulDayKeyMap.put(schedulDayKeyList.get(si).getSwId(), lList);
			}
		}

		// 查询哺乳假期
		List<LactationBean> lactationBeanList = lactationExtDao.getLactationEmployeeList(startDate, endDate,employeeIdList);
		Map<Integer, List<LactationBean>> lactationMap = new HashMap<Integer, List<LactationBean>>();
		for (int li = 0; li < lactationBeanList.size(); li++) {
			if (lactationMap.containsKey(lactationBeanList.get(li).getEmployeeId())) {
				List<LactationBean> lList = lactationMap.get(lactationBeanList.get(li).getEmployeeId());
				lList.add(lactationBeanList.get(li));
				lactationMap.put(lactationBeanList.get(li).getEmployeeId(), lList);
			} else {
				List<LactationBean> lList = new ArrayList<LactationBean>();
				lList.add(lactationBeanList.get(li));
				lactationMap.put(lactationBeanList.get(li).getEmployeeId(), lList);
			}
		}
		
		//查询考勤信息
		AttendanceExample attendanceExample = new AttendanceExample();
		AttendanceExample.Criteria attendanceCriteria = attendanceExample.createCriteria();
		attendanceCriteria.andAttendanceDateBetween(startDate,endDate);
		attendanceCriteria.andEmployeeIdIn(employeeIdList);
		List<Attendance> attendanceList = attendanceDao.selectByExample(attendanceExample);
		
		//循环人员
		for (Employee employee : employeeList) {
			Integer employeeId = employee.getEmployeeId(); 
			//控制循环用的
			Date curDate = DateUtils.addDays(new Date(startDate.getTime()), -1);
			while (curDate.compareTo(endDate) < 0) {
				curDate = DateUtils.addDays(curDate, 1);
				Integer punchTimeId = null;
				Integer swId = null; // 班次ID
				// 判断员工和班次关系是否存在
				if (employeeSchedulMap.containsKey(employeeId)) {
					// 判断员工所属日期范围
					List<EmployeeSchedul> eList = employeeSchedulMap.get(employeeId);
					// 循环判断日期范围是否匹配
					for (int ei = 0; ei < eList.size(); ei++) {
						EmployeeSchedul employeeSchedul = eList.get(ei);
						// 验证日期是否在区间内
						if (TimeUtils.dateCalendar(curDate, employeeSchedul.getFromDate(),employeeSchedul.getThruDate())) {
							punchTimeId = employeeSchedul.getPunchTimeId();
							swId = employeeSchedul.getSwId();
							break;
						}
					}
				}
				if(swId==null && punchTimeId==null){
					continue;
				}
				
				//取得签到数据
				Attendance att=null;
				for(int ai=0;ai<attendanceList.size();ai++){
					if(attendanceList.get(ai).getEmployeeId().equals(employeeId)){
						// 验证日期是否在区间内
						if (curDate.equals(attendanceList.get(ai).getAttendanceDate())) {
							att=attendanceList.get(ai);
							break;
						}
					}
				}
				
				if(att == null){
					continue ;
				}
				
				att.setDescription("");
				//用于存储计算的时间段
				List<String[]>  datatimeList = new ArrayList<String[]>();
				
				//取得打卡记录时间
				String stime=att.getOriginalStartTime();
				String etime=att.getOriginalEndTime();

				//取得打卡时间配置记录
				PunchTime punchTime = null;
				if(punchTimeMap.containsKey(punchTimeId)){
					punchTime =punchTimeMap.get(punchTimeId);
				}
				if (punchTime == null) {
					//未找到打卡时间
					throw new ResultFaultException("5_00008");
				}
				//新员工入职，上班卡8：30
				if (employee.getEntryDate().equals(curDate)) {
					//设置备注
					att.setDescription("入职当天上班卡默认为8:30，实际打卡时间:"+stime);
					stime = punchTime.getStartFromTime();
					att.setOriginalStartTime(stime);//原始打卡时间更改为打卡上班开始时间
				}
				//取得申请通过的补签
				if(retroactiveList != null && retroactiveList.size()>0){
					for (Retroactive retroactive : retroactiveList) {
						if(retroactive.getAttendanceId().equals(att.getAttendanceId())){
							if(!StringUtils.isEmpty(retroactive.getStartTime())){
								if(!StringUtils.isEmpty(att.getOriginalStartTime())){
									if(TimeUtils.compareTime(retroactive.getStartTime(), att.getOriginalStartTime())<0
											|| TimeUtils.compareTime(att.getOriginalStartTime(), "04:00")<0){//打卡时间过0点的情况
										stime = retroactive.getStartTime();
									}
								}else{
									stime = retroactive.getStartTime();
								}
							}
							if(!StringUtils.isEmpty(retroactive.getEndTime())){
								if(!StringUtils.isEmpty(att.getOriginalEndTime())){
									etime = retroactive.getEndTime();//直接取补签时间，不和原始值时间比较了。
								}else{
									etime = retroactive.getEndTime();
								}
							}
						}
					}
				}
				//特殊打卡时间处理，11:45-12:00的打卡时间(开始吃饭时间点)
				if (etime != null) {
					if (TimeUtils.compareTime(etime, "11:45")>=0 && TimeUtils.compareTime(etime, "12:00")<=0) {
						etime="12:00";
					}
				}
				if(!StringUtils.isEmpty(etime) && !StringUtils.isEmpty(stime)){
					//如果下班打卡小于6点，加24小时
					if (TimeUtils.compareTime(stime, "06:00")>0 && TimeUtils.compareTime(etime, "06:00")<=0) {
						etime=TimeUtils.getEndTime(etime, 1440);
					}
				}
				//特殊情况设置
				List<Integer> specialIdList=new ArrayList<>();
				if (employeeSpecialKeyList.size()>0) {
					for (EmployeeSpecialKey employeeSpecialKey : employeeSpecialKeyList) {
						if(employeeSpecialKey.getEmployeeId().equals(employeeId)){
							//获取特殊情况
							if(specialMap.containsKey(employeeSpecialKey.getSpecialId())){
								Special special=specialMap.get(employeeSpecialKey.getSpecialId());
								if(TimeUtils.dateCalendar(curDate, special.getSpecialDate(),  special.getSpecialDate())){
									specialIdList.add(employeeSpecialKey.getSpecialId());
								}
							}
						}
					}
				}
				if (specialIdList.size()>0) {
					List<Special> specialList=new ArrayList<Special>();
					//过滤特殊情况
					for(int sip=0;sip<specialIdList.size();sip++){
						if(specialMap.containsKey(specialIdList.get(sip))){
							Special special=specialMap.get(specialIdList.get(sip));
							specialList.add(special);
						}
					}
					if (specialList.size()>0) {
						for (Special special : specialList) {
							String specialStartTime=special.getStartTime();
							String specialEndTime=special.getEndTime();
							//考勤表添加特殊情况ID
							att.setSpecialId(special.getSpecialId());
							// 设置备注说明
							String description = "系统管理员设置特殊情况：" + special.getSpecialName();
							if (special.getDescription() != null) {
								description += "，说明(" + special.getDescription() + ")";
							}
							att.setDescription(description);
							if (!StringUtils.isEmpty(specialStartTime)) {
								if(!StringUtils.isEmpty(att.getOriginalStartTime())){
									if(TimeUtils.compareTime(specialStartTime, att.getOriginalStartTime())<0){
										stime = specialStartTime;
									}
								} else {
									stime = specialStartTime;
								}
							}
							if (!StringUtils.isEmpty(specialEndTime)) {
								if(!StringUtils.isEmpty(att.getOriginalEndTime())){
									if(TimeUtils.compareTime(specialEndTime, att.getOriginalEndTime())>0){
										etime = specialEndTime;
									}
								} else {
									etime = specialEndTime;
								}
							}
						}
					}
				}
				if(!StringUtils.isEmpty(stime) && !StringUtils.isEmpty(etime)){
					datatimeList.add(new String[]{stime,etime});
				}
				//计算实际出勤时间用
				String actStartTime = stime;
				String actEndTime = etime;
				
				//考虑休息日的情况
				List<SchedulDayKey> schedulDayList =null;
				if (schedulDayKeyMap.containsKey(swId)) {
					schedulDayList = schedulDayKeyMap.get(swId);
					boolean type=true;
					// 循环判断日期范围是否匹配
					for (int si = 0; si < schedulDayList.size(); si++) {
						SchedulDayKey sdk = schedulDayList.get(si);
						// 验证日期是否在区间内
						if (sdk.getSdDate().equals(curDate)) {
							type=false;
							break;
						}
					}
					if(type){
						schedulDayList=null;
					}
				}
				//如果没查到数据，说明是休息日
				if(schedulDayList == null || schedulDayList.size()==0){
					att.setStartTime(actStartTime);
					att.setEndTime(actEndTime);
					att.setAttendanceState(9);
					att.setActualHours(new BigDecimal(0));
					att.setUpdateTime(new Date());
					attendanceDao.updateByPrimaryKeySelective(att);
					continue;
				}
				
				//免签人员
				if(employee.getIsVisaWaiver()==1){
					//取得打卡时间配置记录
					if(punchTimeMap.containsKey(punchTimeId)){
						punchTime =punchTimeMap.get(punchTimeId);
						att.setAttendanceState(1);
						att.setStartTime(actStartTime);
						att.setEndTime(actEndTime);
						//应出勤时长分钟数
						Integer hoursMin=punchTime.getHours();
						att.setActualHours(new BigDecimal(hoursMin));
						att.setUpdateTime(new Date());
						att.setDescription("免签人员");
						//应出勤时长，除去休息
						att.setAttendenceHours(new BigDecimal(hoursMin/60));
						attendanceDao.updateByPrimaryKeySelective(att);
						continue;
					}
				}
				
				//取得应出勤时长（包括中午休息）
				Integer punchMinutes = TimeUtils.differMinutes(punchTime.getStartFromTime(), punchTime.getEndFromTime());
				//休假申请判断
				boolean isDay = false;//是否假期是按天的类型
				//循环请假类型
				for (Request request : requestList) {
					if(!request.getEmployeeId().equals(employeeId)){
						continue;
					}
					if(!TimeUtils.dateCalendar(curDate,request.getStartDate(),request.getEndDate())){
						continue;
					}
					Integer requestType=request.getRequestType();
					//按天请的假期
					if (requestType==3||requestType==4||requestType==11||requestType==13) {
						att.setAttendanceState(1);
						att.setActualHours(new BigDecimal(0));
						att.setStartTime(actStartTime);
						att.setEndTime(actEndTime);
						att.setUpdateTime(new Date());
						attendanceDao.updateByPrimaryKeySelective(att);
						isDay = true;
					} else {
						if(request.getStartDate().compareTo(curDate)==0 && request.getEndDate().compareTo(curDate)==0){
							//申请一天内的情况
							datatimeList.add(new String[]{request.getStartTime(),request.getEndTime()});
						}else if(request.getStartDate().compareTo(curDate)==0 && request.getEndDate().compareTo(curDate)>0){
							//申请跨天第一天内的情况 
							if (request.getStartToTime()==null) {
								//取totime，班次
								datatimeList.add(new String[]{request.getStartTime(),punchTime.getEndToTime()});
							} else {
								datatimeList.add(new String[]{request.getStartTime(),request.getStartToTime()});
							}
						}else if(request.getStartDate().compareTo(curDate)<0 && request.getEndDate().compareTo(curDate)==0){
							//申请跨天最后一天内的情况
							if (TimeUtils.compareTime(request.getEndTime(), punchTime.getStartFromTime())>0) {
								datatimeList.add(new String[]{punchTime.getStartFromTime(),request.getEndTime()});
							}
						}else{
							//请假中间天
							datatimeList.add(new String[]{punchTime.getStartFromTime(),punchTime.getEndFromTime()});
						}
						//整天请假又有打卡的情况2018-02-26
						if(datatimeList.size()>0) {
							String[] dtimes=datatimeList.get(datatimeList.size()-1);
							String requestFromtime=dtimes[0];
							String requestTotime=dtimes[1];
							if (TimeUtils.differMinutes(requestFromtime, requestTotime)>=punchMinutes) {
								att.setAttendanceState(1);
								att.setActualHours(new BigDecimal(0));
								att.setStartTime(actStartTime);
								att.setEndTime(actEndTime);
								att.setUpdateTime(new Date());
								attendanceDao.updateByPrimaryKeySelective(att);
								isDay = true;
							}
						}
					}
				}
				
				//如果是当天申请多天通过后计算考勤是否正确
				if(isDay==false) {
					BigDecimal hours=new BigDecimal(0);
					//循环请假类型
					for (Request request : requestList) {
						if(!request.getEmployeeId().equals(employeeId)){
							continue;
						}
						if(curDate.getTime()==request.getStartDate().getTime()
								&& curDate.getTime()==request.getEndDate().getTime()) {
							Integer requestType=request.getRequestType();
							//判断类型为调休
							if(requestType==0){
								if(request.getHours()!=null) {
									Integer minutes=TimeUtils.differMinutes(request.getStartTime(), request.getEndTime());
									hours=hours.add(new BigDecimal(minutes));
								}
							}
						}
					}
					//如果时间为当天班次时间为正常
					if (hours.intValue()>=punchMinutes) {
						att.setAttendanceState(1);
						att.setActualHours(new BigDecimal(0));
						att.setStartTime(actStartTime);
						att.setEndTime(actEndTime);
						att.setUpdateTime(new Date());
						attendanceDao.updateByPrimaryKeySelective(att);
						isDay = true;
					}
				}
				
				//如果是按天申请的假期，不用后面比较
				if (isDay) {
					continue;
				}
				//没有请假，也没有完整的考勤
				if(datatimeList==null || datatimeList.size()==0){
					att.setAttendanceState(5);
					att.setActualHours(new BigDecimal(0));
					att.setStartTime(actStartTime);
					att.setEndTime(actEndTime);
					att.setUpdateTime(new Date());
					attendanceDao.updateByPrimaryKeySelective(att);
					continue;
				}
				stime = "";
				etime = "";
				//午休时间
				String restFromTime=punchTime.getRestFromTime();
				String restToTime=punchTime.getRestToTime();
				for (String[] datetimes : datatimeList) {
					if(stime == ""){
						stime = datetimes[0];
						etime = datetimes[1];
					}
					for (String[] dtimes : datatimeList) {
						if(TimeUtils.compareTime(stime, dtimes[0])>0 && 
								(TimeUtils.compareTime(stime, dtimes[1])<=0 || (TimeUtils.compareTime(stime, restFromTime)>=0 && TimeUtils.compareTime(dtimes[1], restToTime)<=0))){
							stime = dtimes[0];
						}
						if(TimeUtils.compareTime(etime, dtimes[1])<0 && 
								(TimeUtils.compareTime(etime, dtimes[0])>=0 || (TimeUtils.compareTime(etime, restFromTime)>=0 && TimeUtils.compareTime(dtimes[0], restToTime)<=0))){
							etime = dtimes[1];
						}
					}
				}
				
				//判断哺乳假
				boolean isLactationTrue = false;//是否是：如果都在弹性时间内，又时长不够，但小于30分钟，会被判定为早退的情况
				List<LactationBean> lactationList = null;
				if (lactationMap.containsKey(employeeId)) {
					lactationList=lactationMap.get(employeeId);
				}
				
				if(lactationList!=null && lactationList.size()>0){
					isLactationTrue = true;
					// 循环判断日期是否在，哺乳假期范围内
					for (int lai = 0; lai < lactationList.size(); lai++) {
						LactationBean lab = lactationList.get(lai);
						if (TimeUtils.dateCalendar(curDate,lab.getHbornStartDate(), lab.getEndDate())) {
							//取可休哺乳假时长
							BigDecimal bghours=lab.getHours();
							Integer lacHours = bghours.intValue();
							if(TimeUtils.compareTime(punchTime.getStartToTime(), stime)<0){
								try {
									String[] times = stime.split(":");
									int hour = Integer.parseInt(times[0]);
									stime = String.valueOf(hour-lacHours)+":"+times[1];
								} catch (Exception e) {
								}
								//获取打开早上时间，判断是否大于班次的结束时间，如果大于设置为默认早上最晚结束时间
								if(att.getOriginalStartTime()!=null) {
									if(TimeUtils.compareTime(att.getOriginalStartTime(),punchTime.getEndToTime())>0) {
										stime = punchTime.getStartToTime();
									}
								}
								att.setDescription("早上休哺乳假期");
								isLactationTrue = false;
							}else if(TimeUtils.compareTime(punchTime.getEndFromTime(), etime)>0){
								try {
									String[] times = etime.split(":");
									int hour = Integer.parseInt(times[0]);
									etime = String.valueOf(hour+lacHours)+":"+times[1];
								} catch (Exception e) {
								}
								att.setDescription("晚上休哺乳假期");
								isLactationTrue = false;
							}
							break;
						}
					}
				}
				
				//计算有效时间点
				if(TimeUtils.compareTime(punchTime.getStartFromTime(), stime)>0){
					stime = punchTime.getStartFromTime();
				}
				if(TimeUtils.compareTime(punchTime.getEndToTime(), etime)<0){
					etime = punchTime.getEndToTime();
				}
				
				//取得出勤时长
				Integer dayMinutes = TimeUtils.differMinutes(stime,etime);
				Integer startStatus = 1;
				Integer endStatus = 1;
				//出勤时间不够
				if(dayMinutes < punchMinutes){
					if ((punchMinutes - dayMinutes) > 30) {//如果缺勤时长大于30分钟，旷工
						startStatus = 5;
						endStatus = 5;
					} else {
						boolean isTrue = true;//是否是：如果都在弹性时间内，又时长不够，但小于30分钟，早退
						if(TimeUtils.compareTime(punchTime.getStartToTime(), stime)<0){
							if(TimeUtils.differMinutes(punchTime.getStartToTime(), stime) > punchTime.getStartInterval()){
								// 早旷工
								startStatus = 5;
							}else{
								// 早迟到
								startStatus = 2;
							}
							isTrue = false;
						}
						if(TimeUtils.compareTime(punchTime.getEndFromTime(), etime)>0){
							if(TimeUtils.differMinutes(etime,punchTime.getEndFromTime()) > punchTime.getEndInterval()){
								// 晚 旷工
								endStatus = 5;
							}else{
								// 晚 早退
								endStatus = 3;
							}
							isTrue = false;
						}
						
						//如果都在弹性时间内，又时长不够，但小于30分钟，早退
						if (isTrue) {
							if (isLactationTrue) {//有哺乳假，但：如果都在弹性时间内，又时长不够，但小于30分钟，会被判定为早退的情况
								//正常
								att.setDescription("晚上休哺乳假期");
							} else {
								// 晚 早退
								endStatus = 3;
							}
						}
					}
				}else{
					//正常
				}
				
				if(startStatus == 5 || endStatus == 5){
					//旷工
					att.setAttendanceState(5);
				}else if (startStatus == 2 && endStatus == 1){
					//迟到
					att.setAttendanceState(2);
				}else if (startStatus == 1 && endStatus == 3){
					//早退
					att.setAttendanceState(3);
				}else if (startStatus == 2 && endStatus == 3){
					//迟到并早退
					att.setAttendanceState(5);
				}else{
					//正常
					att.setAttendanceState(1);
				}
				att.setStartTime(actStartTime);
				att.setEndTime(actEndTime);
				//应出勤时长分钟数，除去休息
				Integer hoursMin=punchTime.getHours();
				if(StringUtils.isEmpty(actStartTime) || StringUtils.isEmpty(actEndTime)){
					att.setActualHours(new BigDecimal(0));
				}else{
					Integer actMinutes = getMinutesRemoveRest(actStartTime,actEndTime,punchTime);
					if (actMinutes>hoursMin) {
						actMinutes=hoursMin;
					}
					att.setActualHours(new BigDecimal(actMinutes));
				}
				att.setAttendenceHours(new BigDecimal(hoursMin/60));
				att.setUpdateTime(new Date());
				attendanceDao.updateByPrimaryKeySelective(att);
			}
		}
	}
	
	/*
	 * 去掉午休后剩余时间
	 */
	private Integer getMinutesRemoveRest(String stime,String etime,PunchTime punchTime){
		if (StringUtils.isEmpty(punchTime.getRestFromTime())
				|| StringUtils.isEmpty(punchTime.getRestToTime())) {
			return TimeUtils.differMinutes(stime, etime);
		}
		//申请开始时间小于午休开始时间
		if(TimeUtils.compareTime(stime, punchTime.getRestFromTime())<0){
			//申请结束时间也小于等于 午休开始时间
			if(TimeUtils.compareTime(etime, punchTime.getRestFromTime())<=0){
				return TimeUtils.differMinutes(stime, etime);
			} else{
				//申请结束时间小于午休的结束时间
				if (TimeUtils.compareTime(etime, punchTime.getRestToTime())<0) {
					return  TimeUtils.differMinutes(stime, punchTime.getRestFromTime());
				}
				//申请结束时间大于等于午休的结束时间
				if(TimeUtils.compareTime(etime, punchTime.getRestToTime())>=0){
					return  TimeUtils.differMinutes(stime, punchTime.getRestFromTime()) + TimeUtils.differMinutes(punchTime.getRestToTime(), etime);
				}
			}
		}else{
			//申请开始时间小于午休的结束时间
			if(TimeUtils.compareTime(stime, punchTime.getRestToTime())<0){
				//申请的结束时间大于午休的结束时间
				if(TimeUtils.compareTime(etime, punchTime.getRestToTime())>0){
					return TimeUtils.differMinutes(punchTime.getRestToTime(), etime);
				}else{
					return 0;
				}
			}else{//取申请的开始时间和申请的结束时间时间差
				return TimeUtils.differMinutes(stime, etime);
			}
		}
		return 0;
	}
	
	/*
	 * 计算打卡起止时间
	 */
	@Override
	public String[] getActAttendance(Date curDate,Integer employeeId){
		
		//取得人员的排班时间
		EmployeeSchedulExample employeeSchedulExample = new EmployeeSchedulExample();
		employeeSchedulExample.or().andEmployeeIdEqualTo(employeeId).andFromDateLessThanOrEqualTo(curDate).andThruDateGreaterThanOrEqualTo(curDate);
		employeeSchedulExample.or().andEmployeeIdEqualTo(employeeId).andFromDateLessThanOrEqualTo(curDate).andThruDateIsNull();
		employeeSchedulExample.setOrderByClause("from_date desc");
		List<EmployeeSchedul> employeeSchedulList = employeeSchedulDao.selectByExample(employeeSchedulExample);
		if(employeeSchedulList==null || employeeSchedulList.size()==0){
			//未找到排班信息,后续不处理
			return null;
		}
		
		//取得签到数据
		AttendanceExample attendanceExample = new AttendanceExample();
		AttendanceExample.Criteria attendanceCriteria = attendanceExample.createCriteria();
		attendanceCriteria.andAttendanceDateEqualTo(curDate);
		attendanceCriteria.andEmployeeIdEqualTo(employeeId);
		List<Attendance> attendanceList = attendanceDao.selectByExample(attendanceExample);
		if(attendanceList == null || attendanceList.size()==0){
			return null;
		}
		Attendance att = attendanceList.get(0);
		
		//取得申请通过的补签
		RetroactiveExample retroactiveExample = new RetroactiveExample();
		retroactiveExample.createCriteria().andAttendanceIdEqualTo(attendanceList.get(0).getAttendanceId()).andApprovalStateEqualTo(2);
		List<Retroactive> retroactiveList = retroactiveDao.selectByExample(retroactiveExample);
		String stime="";
		String etime="";
		if(!StringUtils.isEmpty(att.getOriginalStartTime())){
			stime=att.getOriginalStartTime();
		}
		if(!StringUtils.isEmpty(att.getOriginalEndTime())) {
			etime=att.getOriginalEndTime();
		}
		if(retroactiveList != null && retroactiveList.size()>0){
			for (Retroactive retroactive : retroactiveList) {
				if(!StringUtils.isEmpty(retroactive.getStartTime())){
					if(!StringUtils.isEmpty(att.getOriginalStartTime())){
						if(TimeUtils.compareTime(retroactive.getStartTime(), att.getOriginalStartTime())<0){
							stime = retroactive.getStartTime();
						}
					}else{
						stime = retroactive.getStartTime();
					}
				}
				if(!StringUtils.isEmpty(retroactive.getEndTime())){
					if(!StringUtils.isEmpty(att.getOriginalEndTime())){
						if(TimeUtils.compareTime(retroactive.getEndTime(), att.getOriginalEndTime())>0){
							etime = retroactive.getEndTime();
						}
					}else{
						etime = retroactive.getEndTime();
					}
				}
			}
		}
		//特殊情况设置
		EmployeeSpecialExample esExample=new EmployeeSpecialExample();
		esExample.createCriteria().andEmployeeIdEqualTo(employeeId);				
		List<EmployeeSpecialKey> employeeSpecialKeyList=employeeSpecialDao.selectByExample(esExample);
		List<Integer> specialIdList=new ArrayList<>();
		if (employeeSpecialKeyList.size()>0) {
			for (EmployeeSpecialKey employeeSpecialKey : employeeSpecialKeyList) {
				specialIdList.add(employeeSpecialKey.getSpecialId());
			}
		}
		if (specialIdList.size()>0) {
			SpecialExample sExample=new SpecialExample();
			sExample.createCriteria().andSpecialDateEqualTo(curDate)
			.andSpecialIdIn(specialIdList);
			List<Special> specialList=specialDao.selectByExample(sExample);
			if (specialList.size()>0) {
				for (Special special : specialList) {
					String specialStartTime=special.getStartTime();
					String specialEndTime=special.getEndTime();
					if (!StringUtils.isEmpty(specialStartTime)) {
						if(!StringUtils.isEmpty(att.getOriginalStartTime())){
							if(TimeUtils.compareTime(specialStartTime, att.getOriginalStartTime())<0){
								stime = specialStartTime;
							}
						} else {
							stime = specialStartTime;
						}
					}
					if (!StringUtils.isEmpty(specialEndTime)) {
						if(!StringUtils.isEmpty(att.getOriginalEndTime())){
							if(TimeUtils.compareTime(specialEndTime, att.getOriginalEndTime())>0){
								etime = specialEndTime;
							}
						} else {
							etime = specialEndTime;
						}
					}
				}
			}
		}
		return new String[]{stime,etime};
	}
	
	/*
	 * 计算考勤应结束时间 
	 * @param curDate
	 * @param employeeId
	 */
	private String getAttendanceEndTime(Date curDate, Integer employeeId){
		//取出包含当天的申请（不包含补签和加班申请）
		List<Integer> requestTypeList = new ArrayList<Integer>(); 
		requestTypeList.add(0);
		requestTypeList.add(1);
		requestTypeList.add(2);
		requestTypeList.add(3);
		requestTypeList.add(4);
		requestTypeList.add(5);
		requestTypeList.add(6);
		requestTypeList.add(8);
		requestTypeList.add(9);
		requestTypeList.add(11);
		requestTypeList.add(12);
		requestTypeList.add(13);
		
		RequestExample example = new RequestExample();
		example.createCriteria().andStartDateLessThanOrEqualTo(curDate).andEndDateGreaterThanOrEqualTo(curDate)
		.andEmployeeIdEqualTo(employeeId).andRequestTypeIn(requestTypeList)
		.andApprovalStateNotEqualTo(3);//非拒绝的申请 TODO test --update by zx
		List<Request> requestList = requestDao.selectByExample(example);
		
		//取得人员的排班时间
		EmployeeSchedulExample employeeSchedulExample = new EmployeeSchedulExample();
		employeeSchedulExample.or().andEmployeeIdEqualTo(employeeId).andFromDateLessThanOrEqualTo(curDate).andThruDateGreaterThanOrEqualTo(curDate);
		employeeSchedulExample.or().andEmployeeIdEqualTo(employeeId).andFromDateLessThanOrEqualTo(curDate).andThruDateIsNull();
		employeeSchedulExample.setOrderByClause("from_date desc");
		List<EmployeeSchedul> employeeSchedulList = employeeSchedulDao.selectByExample(employeeSchedulExample);
		if(employeeSchedulList==null || employeeSchedulList.size()==0){
			//未找到排班信息,后续不处理
			return null;
		}
		
		//取得签到数据
		AttendanceExample attendanceExample = new AttendanceExample();
		AttendanceExample.Criteria attendanceCriteria = attendanceExample.createCriteria();
		attendanceCriteria.andAttendanceDateEqualTo(curDate);
		attendanceCriteria.andEmployeeIdEqualTo(employeeId);
		List<Attendance> attendanceList = attendanceDao.selectByExample(attendanceExample);
		if(attendanceList == null || attendanceList.size()==0){
			return null;
		}
		Attendance att = attendanceList.get(0);
		
		//用于存储计算的时间段
		List<String[]>  datatimeList = new ArrayList<String[]>();
		
		//取得申请通过的补签
		RetroactiveExample retroactiveExample = new RetroactiveExample();
		retroactiveExample.createCriteria().andAttendanceIdEqualTo(attendanceList.get(0).getAttendanceId()).andApprovalStateEqualTo(2);
		List<Retroactive> retroactiveList = retroactiveDao.selectByExample(retroactiveExample);
		String stime=att.getOriginalStartTime();
		String etime=att.getOriginalEndTime();
		if(retroactiveList != null && retroactiveList.size()>0){
			for (Retroactive retroactive : retroactiveList) {
				if(!StringUtils.isEmpty(retroactive.getStartTime())){
					if(!StringUtils.isEmpty(att.getOriginalStartTime())){
						if(TimeUtils.compareTime(retroactive.getStartTime(), att.getOriginalStartTime())<0){
							stime = retroactive.getStartTime();
						}
					}else{
						stime = retroactive.getStartTime();
					}
				}
				if(!StringUtils.isEmpty(retroactive.getEndTime())){
					if(!StringUtils.isEmpty(att.getOriginalEndTime())){
						if(TimeUtils.compareTime(retroactive.getEndTime(), att.getOriginalEndTime())>0){
							etime = retroactive.getEndTime();
						}
					}else{
						etime = retroactive.getEndTime();
					}
				}
			}
		}
		
		//特殊情况设置
		EmployeeSpecialExample esExample=new EmployeeSpecialExample();
		esExample.createCriteria().andEmployeeIdEqualTo(employeeId);				
		List<EmployeeSpecialKey> employeeSpecialKeyList=employeeSpecialDao.selectByExample(esExample);
		List<Integer> specialIdList=new ArrayList<>();
		if (employeeSpecialKeyList.size()>0) {
			for (EmployeeSpecialKey employeeSpecialKey : employeeSpecialKeyList) {
				specialIdList.add(employeeSpecialKey.getSpecialId());
			}
		}
		if (specialIdList.size()>0) {
			SpecialExample sExample=new SpecialExample();
			sExample.createCriteria().andSpecialDateEqualTo(curDate)
			.andSpecialIdIn(specialIdList);
			List<Special> specialList=specialDao.selectByExample(sExample);
			if (specialList.size()>0) {
				for (Special special : specialList) {
					String specialStartTime=special.getStartTime();
					String specialEndTime=special.getEndTime();
					if (!StringUtils.isEmpty(specialStartTime)) {
						if(!StringUtils.isEmpty(att.getOriginalStartTime())){
							if(TimeUtils.compareTime(specialStartTime, att.getOriginalStartTime())<0){
								stime = specialStartTime;
							}
						} else {
							stime = specialStartTime;
						}
					}
					if (!StringUtils.isEmpty(specialEndTime)) {
						if(!StringUtils.isEmpty(att.getOriginalStartTime())){
							if(TimeUtils.compareTime(specialEndTime, att.getOriginalEndTime())>0){
								etime = specialEndTime;
							}
						} else {
							etime = specialEndTime;
						}
					}
				}
			}
		}
		if(!StringUtils.isEmpty(stime) && !StringUtils.isEmpty(etime)){
			datatimeList.add(new String[]{stime,etime});
		}

		//取得打卡时间配置记录
		PunchTime punchTime = punchTimeDao.selectByPrimaryKey(employeeSchedulList.get(0).getPunchTimeId());
		
		//取得应出勤时长
		Integer punchMinutes = TimeUtils.differMinutes(punchTime.getStartFromTime(), punchTime.getEndFromTime());
		
		for (Request request : requestList) {
			if(request.getStartDate().compareTo(curDate)==0 && request.getEndDate().compareTo(curDate)==0){
				//申请一天内的情况
				datatimeList.add(new String[]{request.getStartTime(),request.getEndTime()});
			}else if(request.getStartDate().compareTo(curDate)==0 && request.getEndDate().compareTo(curDate)>0){
				//申请跨天第一天内的情况 
				if (request.getStartToTime()==null) {
					//取totime，班次
					datatimeList.add(new String[]{request.getStartTime(),punchTime.getEndToTime()});
				} else {
					datatimeList.add(new String[]{request.getStartTime(),request.getStartToTime()});
				}
			}else if(request.getStartDate().compareTo(curDate)<0 && request.getEndDate().compareTo(curDate)==0){
				//申请跨天最后一天内的情况
				if (TimeUtils.compareTime(request.getEndTime(), punchTime.getStartFromTime())>0) {
					datatimeList.add(new String[]{punchTime.getStartFromTime(),request.getEndTime()});
				}
			}else{
				//请假中间天
				datatimeList.add(new String[]{punchTime.getStartFromTime(),punchTime.getEndFromTime()});
			}
		}
		//没有请假，也没有完整的考勤
		if(datatimeList==null || datatimeList.size()==0){
			return null;
		}
		
		stime = "";
		etime = "";
		//午休时间
		String restFromTime=punchTime.getRestFromTime();
		String restToTime=punchTime.getRestToTime();
		for (String[] datetimes : datatimeList) {
			if(stime == ""){
				stime = datetimes[0];
				etime = datetimes[1];
			}
			for (String[] dtimes : datatimeList) {
				if(TimeUtils.compareTime(stime, dtimes[0])>0 && 
						(TimeUtils.compareTime(stime, dtimes[1])<=0 || (TimeUtils.compareTime(stime, restFromTime)>=0 && TimeUtils.compareTime(dtimes[1], restToTime)<=0))){
					stime = dtimes[0];
				}
				if(TimeUtils.compareTime(etime, dtimes[1])<0 && 
						(TimeUtils.compareTime(etime, dtimes[0])>=0 || (TimeUtils.compareTime(etime, restFromTime)>=0 && TimeUtils.compareTime(dtimes[0], restToTime)<=0))){
					etime = dtimes[1];
				}
			}
		}
		
		//判断哺乳假
		LactationExample lacExample = new LactationExample();
		lacExample.createCriteria().andEmployeeIdEqualTo(employeeId).andHbornStartDateLessThanOrEqualTo(curDate).andEndDateGreaterThanOrEqualTo(curDate);
		List<Lactation> lactationList = lactationDao.selectByExample(lacExample);
		//如果有哺乳假
		Boolean isLactation = false;
		//哺乳假时长
		Integer lacHours = 0;
		if(lactationList!=null && lactationList.size()>0){
			isLactation = true;
			//取可休哺乳假时长
			BigDecimal bghours=lactationList.get(0).getHours();
			lacHours = bghours.intValue();
			if(TimeUtils.compareTime(punchTime.getStartToTime(), stime)<0){
				isLactation = false;//如果考勤时长不足，则哺乳假已使用
				try {
					String[] times = stime.split(":");
					int hour = Integer.parseInt(times[0]);
					stime = String.valueOf(hour-lacHours)+":"+times[1];
				} catch (Exception e) {
				}
			}else if(TimeUtils.compareTime(punchTime.getEndFromTime(), etime)>0){
				isLactation = false;//如果考勤时长不足，则哺乳假已使用
				try {
					String[] times = etime.split(":");
					int hour = Integer.parseInt(times[0]);
					etime = String.valueOf(hour+lacHours)+":"+times[1];
				} catch (Exception e) {
				}
			}
		}
		
		//计算有效时间点
		if(TimeUtils.compareTime(punchTime.getStartFromTime(), stime)>0){
			stime = punchTime.getStartFromTime();
		}
		if(TimeUtils.compareTime(punchTime.getEndToTime(), etime)<0){
			etime = punchTime.getEndToTime();
		}
		if (isLactation) {
			punchMinutes = punchMinutes - lacHours * 60;
		}
		String accEtime = TimeUtils.getEndTime(stime, punchMinutes);
		
		if(TimeUtils.compareTime(etime, accEtime)>0){
			return accEtime;
		}else{
			return etime;
		}
	}

	/**
	 * 计算早上加班时长（分钟）--张鑫
	 */
	@Override
	public Integer getMorningMinutes(RequestBean requestBean) {
		Date startDate=requestBean.getStartDate();
		//加班开始时间
		String startTime=requestBean.getStartTime();
		//加班结束时间
		String endTime=requestBean.getEndTime();
		Integer employeeId=requestBean.getEmployeeId();
		//取得当天的考勤数据
		String[] attTimes = getActAttendance(startDate,employeeId);
		if(attTimes==null){
			throw new ResultFaultException("4_00017");
		}
		String stime = attTimes[0];//早上卡时间
		String etime = attTimes[1];//早上卡时间
		if(StringUtils.isEmpty(stime) && !StringUtils.isEmpty(etime)){
			//考勤信息不完整
			throw new ResultFaultException("4_00014"); 
		} else if(!StringUtils.isEmpty(stime) && StringUtils.isEmpty(etime)){
			//考勤信息不完整
			throw new ResultFaultException("4_00014"); 
		} else if(StringUtils.isEmpty(stime) && StringUtils.isEmpty(etime)){
			//缺少考勤信息！
			throw new ResultFaultException("4_00017");
		}
		//取得人员的排班时间
		EmployeeSchedulExample employeeSchedulExample = new EmployeeSchedulExample();
		employeeSchedulExample.or().andEmployeeIdEqualTo(employeeId).andFromDateLessThanOrEqualTo(startDate).andThruDateGreaterThanOrEqualTo(startDate);
		employeeSchedulExample.or().andEmployeeIdEqualTo(employeeId).andFromDateLessThanOrEqualTo(startDate).andThruDateIsNull();
		employeeSchedulExample.setOrderByClause("from_date Desc");
		List<EmployeeSchedul> employeeSchedulList = employeeSchedulDao.selectByExample(employeeSchedulExample);
		if(employeeSchedulList==null || employeeSchedulList.size()==0){
			//未找到排班信息
			throw new ResultFaultException("5_00006"); 
		}
		//取得打卡时间配置记录
		PunchTime punchTime = punchTimeDao.selectByPrimaryKey(employeeSchedulList.get(0).getPunchTimeId());
		String startFromTime = punchTime.getStartFromTime();
		//比较早上打卡时间和申请开始时间
		if (TimeUtils.compareTime(stime, startTime) > 0) {
			throw new ResultFaultException("4_00009");
		}
		if (TimeUtils.compareTime(stime, etime) < 0) {
			//申请结束时间endTime的比较
			if (TimeUtils.compareTime(startFromTime, endTime) < 0 || TimeUtils.compareTime(etime, endTime) < 0) {
				throw new ResultFaultException("4_00021");
			}
		}
		//早上打卡时间和上班时间比较
		if (TimeUtils.compareTime(stime, startFromTime) > 0) {
			throw new ResultFaultException("4_00020");
		}
		//计算早上加班时长
		if (TimeUtils.compareTime(startTime, stime) < 0) {
			startTime = stime;
		}
		if (TimeUtils.compareTime(endTime, startFromTime) > 0) {
			endTime = startFromTime;
		}
		Integer morningMinutes=TimeUtils.differMinutes(startTime, endTime);
		if (morningMinutes < 0) {
			throw new ResultFaultException("4_00018");
		}
		return morningMinutes;
	}
	
	/**
	 * 邮件提醒
	 * @param employeeId 接收者id
	 * @param textPart 正文
	 * @param requestId 申请(或补签)id
	 * @param requestType 申请类型	99是补签，88是工资申请
	 * 忘记密码 requestId==null, requestType==null
	 */
	@Override
	public void sendEmail(Integer employeeId, String textPart,Integer kindsRequestId, Integer requestType) {
	
		//查询初始化表
		SystemConfigure systemConfigure=systemConfigureDao.selectByPrimaryKey(1);
		if (systemConfigure.getIsMail()==0 && kindsRequestId!=null) {//kindsRequestId==null是重置密码
			//不发邮件
		} else {
			//接收者邮箱
			Employee employee = employeeDao.selectByPrimaryKey(employeeId);
			
			//邮件内容
			SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm");
			Date nowDate = new Date();
			long now = nowDate.getTime();
			String str = now + employee.getEmail();
			MD5Util md5 = new MD5Util();
			String key=md5.getMD5ofStr(str);
			
			//把key(密钥)写入数据库地址表
			LinkAddress linkAddress = new  LinkAddress();
			linkAddress.setEmployeeId(employee.getEmployeeId());
			linkAddress.setUrlKey(key);
			if (kindsRequestId == null) {//忘记密码
				linkAddress.setType(0);//1，是审批，，0，是忘记密码
			} else {//申请
				linkAddress.setType(1);//1，是审批，，0，是忘记密码
				//设置申请id
				if (requestType==99) {//补签
					linkAddress.setRetroactiveId(kindsRequestId);
				} else if(requestType==88) {//工资申请
					linkAddress.setSalaryRequestId(kindsRequestId);
				} else {//其它申请
					linkAddress.setRequestId(kindsRequestId);
				}
			}
			//pathNum
			String pathNum = null;
			if (requestType != null) {
				if (requestType==7) {//加班
					pathNum = "ot";//overtime
				} else if (requestType==8) {//出差
					pathNum = "bt";//businessTrip
				} else if (requestType==9) {//外出
					pathNum = "go";//goOut
				} else if (requestType==99) {//补签申请
					pathNum = "rr";//retroactiveRequest
				} else if (requestType==88) {//工资申请
					pathNum = "sr";//salaryRequest
				} else {//其它申请
					pathNum = "or";//othersRequest
				}
			}
			linkAddressDao.insertSelective(linkAddress);
			
			String mailStr=null;
			String url=null;
			if (pathNum!=null) {
				mailStr=MailUtils.toGBK(AppConstant.MAIL_APPROVAL_CONTENT);
				url="key="+ key +"&pathNum="+ pathNum;
			} else {
				mailStr=MailUtils.toGBK(AppConstant.MAIL_FORGET_PASSWORD_CONTENT);
				url="key="+ key;
			}
			textPart=textPart+mailStr.replace("@s", sdf.format(nowDate)).replace("@u", url);
			
			//发邮件
			MailUtils.send(systemConfigure, employee.getEmail(), AppConstant.MAIL_TITLE,textPart, AppConstant.MAIL_ENDING);
		}
	}
	
	/**
	 * 驳回时发送邮件
	 * @param employeeId
	 * @param textPart
	 */
	@Override
	public void sendEmailByReject(Integer employeeId, String textPart,String description) {
		//查询初始化表
		SystemConfigure systemConfigure=systemConfigureDao.selectByPrimaryKey(1);
		if (systemConfigure.getIsMail()==0) {
			//不发邮件
		} else {
			//接收者邮箱
			Employee employee = employeeDao.selectByPrimaryKey(employeeId);
			//邮件内容
			SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm");
			String rejcet=MailUtils.toGBK(AppConstant.MAIL_REJECT_CONTENT);
			if (description==null) {
				textPart=textPart+rejcet.replace("@s", sdf.format(new Date())).replace("@c", "");
			} else {
				textPart=textPart+rejcet.replace("@s", sdf.format(new Date())).replace("@c", description);
			}
			//发邮件
			MailUtils.send(systemConfigure, employee.getEmail(), AppConstant.MAIL_TITLE,textPart, AppConstant.MAIL_ENDING);
		}
	}
	
	/**
	 * 删除一般申请的邮件链接key
	 * @param kindsRequestId
	 */
	@Override
	public void deleteLinkAdd(Integer requestId) {
		LinkAddressExample laExample = new LinkAddressExample();
		laExample.createCriteria().andRequestIdEqualTo(requestId);
		linkAddressDao.deleteByExample(laExample);
	}
	
	/**
	 * 插入任务表数据
	 * @param taskDate
	 * @param employeeId
	 */
	private void insertTask (Date taskDate, Integer employeeId) {
		Task task = new Task();
		task.setEmployeeId(employeeId);
		task.setState(0);
		task.setTaskDate(taskDate);
		taskDao.insertSelective(task);
	}

	/**
	 * 判断，然后插入任务表数据
	 */
	@Override
	public void insertTaskByParam(Date taskDate, Integer employeeId) {
		//插入任务表数据
		TaskExample taskExample = new TaskExample();
		taskExample.createCriteria().andEmployeeIdEqualTo(employeeId)
		.andTaskDateEqualTo(taskDate)
		.andStateEqualTo(0);
		List<Task> taskList = taskDao.selectByExample(taskExample);//查询是否已有数据
		if (taskList.size()==0) {
			this.insertTask(taskDate, employeeId);
		}
	}
	
}
